Haskell String to Maybe List

时间:2016-04-06 08:09:50

标签: haskell

readSquareTransition :: String -> Maybe [SquareTurn]
readSquareTransition [] = Just []
readSquareTransition (x:xs) = case x of
      'L' -> Just (L : readSquareTransition xs)
      'R' -> Just (R : readSquareTransition xs)
       _      -> Nothing

我想得到Just [L,L,R,R]。但看起来我失败了:(这是错误信息!

src/StudentSources/LangtonsAnt.hs:231:24:
Couldn't match expected type ‘[SquareTurn]’
            with actual type ‘Maybe [SquareTurn]’
In the second argument of ‘(:)’, namely ‘readSquareTransition xs’
In the first argument of ‘Just’, namely
  ‘(L : readSquareTransition xs)’

src/StudentSources/LangtonsAnt.hs:232:24:
Couldn't match expected type ‘[SquareTurn]’
            with actual type ‘Maybe [SquareTurn]’
In the second argument of ‘(:)’, namely ‘readSquareTransition xs’
In the first argument of ‘Just’, namely
  ‘(R : readSquareTransition xs)’

2 个答案:

答案 0 :(得分:3)

更改此

'L' -> Just (L : readSquareTransition xs)
'R' -> Just (R : readSquareTransition xs)

到这个

'L' -> fmap (L :) $ readSquareTransition xs
'R' -> fmap (R :) $ readSquareTransition xs

问题是readSquareTransition返回Maybe [SquareTurn],因此您无法将(:)应用于它((:)需要List)。但是,fmap允许您应用Just(同时保留Nothing)。

答案 1 :(得分:3)

这样做的模块化方法是首先定义readSquareTurn,定义如何将Char转换为单SquareTurn(可能会失败):

readSquareTurn :: Char -> Maybe SquareTurn
readSquareTurn x = case x of
  'L' -> Just L
  'R' -> Just R
  _   -> Nothing

然后使用mapM :: (a -> Maybe b) -> [a] -> Maybe [b]来处理整个String,如下所示:

readSquareTransition :: String -> Maybe [SquareTurn]
readSquareTransition = mapM readSquareTurn