Haskell从另一个函数检查函数的返回类型

时间:2013-12-07 23:08:54

标签: haskell recursion

我有一个Haskell代码,它有两个函数:

第一个功能:

functionA :: [Int] -> Maybe Int

第二个:

functionB :: Int -> Maybe Int

我想要做的是递归[Int]的每个元素并将其提供给functionB。如果函数B返回一个Int,那么移动到下一个元素,如果它返回Nothing,那么functionA也不返回任何内容。

知道如何做到最好吗?

谢谢:)

3 个答案:

答案 0 :(得分:3)

您可以使用sequence[Maybe Int]带到Maybe [Int]

functionA ints = sequence (map functionB ints)

通常,sequencemap的这种组合称为mapM

functionA ints = mapM functionB ints

答案 1 :(得分:1)

你的问题有一些不清楚的事情因此我做了一些假设。 functionA就像将[Int]转换为Maybe Int一样折叠,但在折叠整数之前,它会调用functionB将每个整数转换为Maybe Int其中Nothing 1}}结果表示转换失败,导致functionA失败并使其返回Nothing

import Control.Applicative

functionA :: [Int] -> Maybe Int
functionA nums = foldl (\x y -> (+) <$> x <*> y) (Just 0) $ map functionB nums

functionB :: Int -> Maybe Int
functionB 2 = Nothing
functionB x = Just (x+x)

在上面的示例中,+用于折叠操作,functionB在数字2上失败

答案 2 :(得分:0)

学家亚伯拉罕森回答说得对,但是他把结果函数命名为异常并让你感到困惑。

让我们注意:

ints :: [a]

functionA :: [a] -> Maybe a

functionB :: a -> Maybe a

所以我们希望得到地图functionB

functionC :: a -> Maybe [a]
functionC ints = mapM functionB ints

functionC的结果类型为Maybe [a],而非[a],因此我们使用fmap

result :: [a] -> Maybe a
result ints = join $ fmap functionA $ functionC ints

我们还使用join来删除Maybe (Maybe a)结果

或者让我们写一行:

result :: [a] -> Maybe a
result = join . fmap functionA . mapM functionB

<强>已更新

但在此解决方案中始终计算所有ints。 如果我们希望停止计算,我们需要mapIfAllJust函数,如下所示:

result :: [a] -> Maybe a
result = join . fmap functionA . sequence . mapIfAllJust functionB

mapIfAllJust :: (a -> Maybe b) -> [a] -> [Maybe b]
mapIfAllJust _ []     = []
mapIfAllJust f (x:xs) = go f (f x) [] xs
where
    go _ Nothing _    _         = [Nothing]
    go _ pr      used []        = pr : used
    go f pr      used (nxt:rst) = go f (f nxt) (pr : used) rst