haskell - 为什么我不能仅使用 Functor/Applicative 约束来实现这些函数?

标签 haskell monads

考虑以下函数,取自 the answers到此 problem set :

func6 :: Monad f => f Integer -> f (Integer,Integer)
func6 xs = do
    x <- xs
    return $ if x > 0 then (x, 0)
                      else (0, x)

func6' :: Functor f => f Integer -> f (Integer,Integer)
-- slightly unorthodox idiom, with an partially applied fmap
func6' = fmap $ \x -> if x > 0 then (x,0) else (0,x)

-- func7 cannot be implemented without Monad if we care about the precise
-- evaluation and layzness behaviour:
-- > isJust (func7 (Just undefined))
-- *** Exception: Prelude.undefined
--
-- If we care not, then it is equivalent to func6, and there we can. Note that
-- > isJust (func6 (Just undefined))
-- True    
func7 :: Monad f => f Integer -> f (Integer,Integer)
func7 xs = do
    x <- xs
    if x > 0 then return (x, 0)
             else return (0, x)

-- func9 cannot be implemented without Monad: The structure of the computation
-- depends on the result of the first argument.
func9 :: Monad f => f Integer -> f Integer -> f Integer -> f Integer
func9 xs ys zs = xs >>= \x -> if even x then ys else zs

虽然我理解func7的反例,我不明白为什么我们可以实现 func7 的给定推理和 func9仅使用 monad。 monad/applicative/functor 定律如何符合上述推理?

最佳答案

我认为这里不需要担心 typeclass 法;事实上,如果您的目的是理解非严格性,我认为类型类不必要地使练习复杂化。

这是一个更简单的示例,其中所有内容都是单态的,我们将使用 :sprint 而不是使用底部给出示例。在 GHCi 中观看评价的程度。

功能6

我的 x6这里的例子对应于 func6在问题中。

λ> x6 = Just . bool 'a' 'b' =<< Just True

最初,没有评估任何内容。
λ> :sprint x6
x6 = _

现在我们评估'isJust x6'。
λ> isJust x6
True

现在我们可以看到 x6已部分评估。不过,只是到了它的头上。
λ> :sprint x6
y = Just _

为什么?因为没有必要知道 bool 'a' 'b' 的结果部分只是确定是否Maybe将是 Just .所以它仍然是一个未经评估的重击。

功能7

我的 x7这里的例子对应于 func7在问题中。
λ> x7 = bool (Just 'a') (Just 'b') =<< Just True
x :: Maybe Char

同样,最初没有评估任何内容。
λ> :sprint x7
x = _

我们将再次申请 isJust .
λ> isJust x7
True

在这种情况下,Just 的内容确实得到了评​​估(所以我们说这个定义“更严格”或“不那么懒惰”)。
λ> :sprint x7
x = Just 'b'

为什么?因为我们必须评估 bool应用程序之前我们可以判断它是否会产生 Just结果。

关于haskell - 为什么我不能仅使用 Functor/Applicative 约束来实现这些函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49301663/

相关文章:

haskell - 声明适用于具有特定字段的 Vinyl 记录的约束

arrays - 矩阵作为应用仿函数,不是 Monad

haskell - 为什么 "return Nothing"什么都不返回?

haskell - 一个简单的例子表明 IO 不满足单子(monad)定律?

haskell - 读者单子(monad)的目的是什么?

haskell - Haskell Bag(多集)实现

haskell - 为什么此 SBV 代码在达到我设置的限制之前停止?

recursion - 在 F# 中使用免费 monad 是否意味着更长的启动时间和有限的指令?

haskell - 使用 GHC 仅分析单个功能(或成本中心)

haskell - 什么是Ord类型?