如何正确使用Maybe base?

时间:2016-08-26 13:01:54

标签: haskell

我编写了一个代码来将字符串转换为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'

为什么会这样......

3 个答案:

答案 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)