我编写了一个代码来将字符串转换为Intger列表:
convert::String -> Maybe [Int]
convert (c:cs)
isDigit c = Just(c: (convert cs):[])
otherwise = Nothing
并显示错误...
test.hs:15:26: error:
parse error on input ‘=’
Perhaps you need a 'let' in a 'do' block?
e.g. 'let x = 5' instead of 'x = 5'
为什么会这样......
答案 0 :(得分:5)
虽然您的代码中存在其他编译错误,但您收到有关解析错误的错误消息的原因是因为您未包含警卫中使用的管道字符。
convert (c:cs)
| isDigit c = Just(c: (convert cs):[])
| otherwise = Nothing
答案 1 :(得分:4)
您的代码中存在多个错误。您需要尝试转换每个字符,这会产生Maybe Int
。然后使用mapM
monad中的Maybe
循环播放字符串:
import Data.Char
convertChar :: Char -> Maybe Int
convertChar c = if isDigit c then Just $ ord c else Nothing
convert :: String -> Maybe [Int]
convert = mapM convertChar
答案 2 :(得分:2)
查看V. Semeria's answer的另一种方法是将sequence
(来自Traversable
类型类)与map
一起使用:
import Data.Char -- for ord
convertChar :: Char -> Maybe Int
convertChar c = if isDigit c then Just $ ord c - 48 else Nothing
convert :: String -> Maybe [Int]
-- Start with String -> [Maybe Int], then convert
-- the [Maybe Int] to Maybe [Int]
convert = sequence . map convertChar
这是一种常见模式,因此Traversable
也提供traverse
,在这种情况下相当于sequence . map
。
convert :: Traversable t => t Char -> Maybe (t Int)
convert = traverse converChar
一些示例(默认情况下,Traversable
的大多数实例都不是很有趣,但各种树类型都可以有实例)。
> convert "123"
Just [1,2,3]
> convert (Just '1')
Just (Just 1)
> convert (True, '2')
Just (True, 2)
> convert (Right '1')
Just (Right 1)