2014年1月29日水曜日

開発環境

Real World Haskell―実戦で学ぶ関数型言語プログラミング(Bryan O'Sullivan (著)、 John Goerzen (著)、 Don Stewart (著)、山下 伸夫 (翻訳)、伊東 勝利 (翻訳)、株式会社タイムインターメディア (翻訳)、オライリージャパン)の4章(関数プログラミング)、4.6(ループをどのように考えるか)、4.6.9(左畳み込み、遅延性、スペースリーク)、練習問題 3.を解いてみる。

その他参考書籍

練習問題 3.

コード(BBEdit, Emacs)

InteractWith.hs

{-# OPTIONS -Wall -Werror #-}
module Main where

import Data.Char(digitToInt, isDigit)

type ErrorMessage = String

asIntFold :: String -> Either ErrorMessage Int
asIntFold xs = let m = fromIntegral (maxBound :: Int) :: Integer
               in case asIntegerFold xs of
                       Left s -> Left s
                       Right n -> if n <= m
                                  then Right ((fromIntegral n) :: Int)
                                  else Left "bound error"

asIntegerFold :: String -> Either ErrorMessage Integer
asIntegerFold [] = Left "empty"
asIntegerFold ('-':xs) = case asIntegerFold xs of
                              Left s -> Left s
                              Right n -> Right (- 1 * n)
asIntegerFold xs =
    let n = length xs
    in foldr step (Right 0) (zip xs [n - 1, n - 2..])

step :: (Char, Int) -> Either String Integer -> Either String Integer
step _ (Left x) = Left x
step (c, n) (Right y) =
    if isDigit c
    then Right (y + (fromIntegral (digitToInt c) :: Integer) * (10 ^ n))
    else Left ("non-digit '" ++ c:"'")

integers2right :: [Integer] -> [Either a Integer]
integers2right = foldr (\x acc -> Right x:acc) []

入出力結果(Terminal, インタプリタghci)

$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :load exercises.hs 
[1 of 1] Compiling Main             ( exercises.hs, interpreted )
Ok, modules loaded: Main.
*Main> asIntFold "101"
Right 101
*Main> asIntFold "-31337"
Right (-31337)
*Main> asIntFold "1798"
Right 1798
*Main> asIntFold ""
Left "empty"
*Main> asIntFold "-"
Left "empty"
*Main> asIntFold "-3"
Right (-3)
*Main> asIntFold "2.7"
Left "non-digit '.'"
*Main> asIntFold "314159265358979323846"
Left "bound error"
*Main> asIntFold "33"
Right 33
*Main> asIntFold "foo"
Left "non-digit 'o'"
*Main> :quit 
Leaving GHCi.
$

0 コメント:

コメントを投稿