「48時間でSchemeを書こう/練習問題の解答」の版間の差分

削除された内容 追加された内容
一部訳出
M →‎練習問題2: マークアップ
95 行
First, it is necessary to change the definition of symbol.
 
<syntaxhighlight lang="haskell">
symbol :: Parser Char
symbol :: Parser Char
symbol = oneOf "!$%&|*+-/:<=>?@^_~"
</syntaxhighlight>
 
This means that it is no longer possible to begin an atom with the hash character. This necessitates a different way of parsing #t and #f.
 
<syntaxhighlight lang="haskell">
parseBool :: Parser LispVal
parseBool =:: doParser string "#"LispVal
parseDigital2parseBool = do try $ string "#d"
x <- oneOf "tf"
x return $ case x<- ofoneOf "tf"
return $ case x of 't' -> Bool True
'ft' -> Bool FalseTrue
x < 'f' -> oneOfBool "tf"False
</syntaxhighlight>
 
This in turn requires us to make changes to parseExpr.
 
<syntaxhighlight lang="haskell">
parseExpr :: Parser LispVal
parseExpr =:: parseAtomParser LispVal
parseExpr = parseAtom
<|> parseString
<|> parseNumberparseString
<|> parseBoolparseNumber
<|> parseStringparseBool
 
</syntaxhighlight>
 
parseNumber need to be changed to the following.
 
<syntaxhighlight lang="haskell">
parseNumber :: Parser LispVal
parseNumber :: Parser LispVal
parseNumber = do num <- parseDigital1 <|> parseDigital2 <|> parseHex <|> parseOct <|> parseBin
return $ num
</syntaxhighlight>
 
And the following new functions need to be added.
 
<syntaxhighlight lang="haskell">
parseBoolparseDigital1 :: Parser LispVal
parseDigital1 = do x <- many1 digit
(return . Number . read) x
 
parseDigital1parseDigital2 :: Parser LispVal
parseDigital1parseDigital2 = do xtry <-$ many1string digit"#d"
(return . Number . read) x <- many1 digit
(return x. <-Number many1. digitread) x
 
parseDigital2 :: Parser LispVal
parseDigital2 = do try $ string "#d"
x <- many1 digit
(return . Number . read) x
 
parseHex :: Parser LispVal
parseHex = do try $ string "#x"
x <- many1 hexDigit
return $ Number (hex2dig x)
 
parseOct :: Parser LispVal
parseOct = do try $ string "#o"
x <- many1 octDigit
return $ Number (oct2dig x)
 
parseBin :: Parser LispVal
parseBin = do try $ string "#b"
x <- many1 (oneOf "10")
return $ Number (bin2dig x)
 
oct2dig x = fst $ readOct x !! 0
hex2dig x = fst $ readHex x !! 0
bin2dig = bin2dig' 0
bin2dig' digint "" = digint
bin2dig' digint (x:xs) = let old = 2 * digint + (if x == '0' then 0 else 1) in
bin2dig' old xs
</syntaxhighlight>
 
</li>