通过替换值得到错误的结果

时间:2017-08-10 07:45:06

标签: haskell

我有以下功能:

meh :: (Functor m, Monad m) => [a] -> (a -> m b) -> m [b]
meh [] _ = return []
meh (x:xs) f = do
  x' <- f x
  fmap ((:) x') (meh xs f)

然后我在前奏中尝试如下,我已经得到了:

*ExerciseMonad Control.Monad> meh [3,4,5] (\x -> Just x)
Just [3,4,5]

但我确实期待[Just 3, Just 4, Just 5]

为了找出问题,我做了替换:

meh [3,4,5] (\x -> Just x) = Just [3,4,5]

meh (3:[4,5])] (\x -> Just x) =
  Just 3 <- (\3 -> Just 3)
  fmap ((:) (Just 3)) (meh [4,5] (\x -> Just x))

meh (4:[5])] (\x -> Just x) =
  Just 4 <- (\4 -> Just 4)
  fmap ((:) (Just 4)) (meh [5] (\x -> Just x))

meh ([5])] (\x -> Just x) =
  Just 5 <- (\5 -> Just 5]
  fmap ((:) (Just 5)) (meh [] (\x -> Just x))

meh [] _ = return []  


--all the way back
meh ([5])] (\x -> Just x) = fmap ((:) (Just 5)) []
meh (4:[5])] (\x -> Just x) = fmap ((:) (Just 4)) [Just 5] <- result [Just 4, Just 5]
meh (3:[4,5])] (\x -> Just x) = fmap ((:) (Just 3)) [Just 4, Just 5] <- result [Just 4, Just 5]
meh [3,4,5] (\x -> Just x) = [Just 3,Just 4, Just 5]

如您所见,替换与正确的结果不匹配:

Just [3,4,5] != [Just 3,Just 4, Just 5]

我的问题,我对替换的错误是什么?我得到了错误的结果?

2 个答案:

答案 0 :(得分:2)

根据类型,一切正常

meh :: (Functor m, Monad m) => [a] -> (a -> m b) -> m [b]

如果您期待[Just 3, Just 4, Just 5],可能需要以下内容:

meh :: (Functor m, Monad m) => [a] -> (a -> m b) -> [m b]

或者只是

meh :: (Functor m) => [a] -> (a -> m b) -> [m b]

因为如果你不想加入价值观,你就不需要monad实例。

meh' :: (Functor m, Monad m) => [a] -> (a -> m b) -> [m b]
meh' [] _ = []
meh' (x:xs) f =
  (f x) : (meh' xs f)

致电meh' [3,4,5] Just返回[Just 3, Just 4, Just 5]

致电meh [3,4,5] Just返回Just [3,4,5]

谈论替换(从空列表开始):

meh [] _ = Just [],因为meh [] _ = return []返回一个包含在monadic结构中的空列表(在本例中为Maybe monad)

meh (5:[]) (\x -> Just x) = do
  x' <- (\x -> Just x) 5
  fmap ((:) x') (meh [] (\x -> Just x))

在此步骤x' <- (x -> Just x) 5x'绑定到5。这就是为什么meh [5] Just转换为fmap ((:) 5) (Just [])等于Just [5],而不是fmap ((:) (Just 5)) []确实等于[Just 5]

的原因

答案 1 :(得分:0)

正如我在您的类型签名错误之前所评论的那样: 如果您检查[Just 1, Just 2, ...]的类型是[m b]而不是m []

此外,您无法简化您的功能:

meh :: (Functor m, Monad m) => [a] -> (a -> m b) -> [m b]
meh l f = fmap f l

这里有life example

您在此步骤中的替换是错误的:

x' <- f x

由于你在monad中工作,你绑定(<-}到x'里面的值 monad(在这种情况下为Just)所以'x''将是3(4,5,...)而不是Just 3