【问题标题】:Haskell checking return type of function from another functionHaskell 检查另一个函数的返回类型
【发布时间】:2013-12-07 23:08:53
【问题描述】:

我有一个 Haskell 代码,它有两个功能:

第一个函数:

functionA :: [Int] -> Maybe Int

第二个:

functionB :: Int -> Maybe Int

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

知道如何最好地做到这一点吗?

谢谢:)

【问题讨论】:

  • 你的意思是你想用functionBfunctionA?如果多个Ints 给出Int 而不是Nothing,会发生什么情况?只返回第一个有效的,还是返回所有有效的列表?

标签: haskell recursion


【解决方案1】:

您可以使用sequence[Maybe Int] 转为Maybe [Int]

functionA ints = sequence (map functionB ints)

通常sequencemap 的这种组合称为mapM

functionA ints = mapM functionB ints

【讨论】:

  • 对此有点困惑,能否详细说明一下?
【解决方案2】:

您的问题几乎没有不清楚的地方,因此我做出的假设很少。 functionA 就像一个折叠,因为它将[Int] 转换为Maybe Int,但在折叠整数之前,它调用functionB 将每个整数转换为Maybe Int,其中Nothing 结果表示转换失败并导致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 上失败

【讨论】:

    【解决方案3】:

    J。 Abrahamson 回答正确,但他将结果函数命名为异常,这让您感到困惑。

    让我们有整数:

    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    
    

    【讨论】:

      猜你喜欢
      • 2015-12-12
      • 2012-02-27
      • 2018-11-27
      • 1970-01-01
      • 2017-12-04
      • 2020-12-11
      • 1970-01-01
      • 2021-12-23
      • 2021-12-01
      相关资源
      最近更新 更多