gpt4 book ai didi

validation - 将 monadic 验证变成应用程序?

转载 作者:行者123 更新时间:2023-12-05 08:22:00 25 4
gpt4 key购买 nike

我需要验证数字输入是否在特定范围内。为此,我正在使用

ensure :: (a -> Bool) -> a -> Maybe a
ensure p v | p v = Just v
| otherwise = Nothing

检查某个值 x::Int 上限和下限的一种方法是通过单子(monad)链:

let validated = pure x >>= ensure (>0) >>= ensure (<100)

据我了解,两次验证的顺序无关紧要;因此,应该有可能以应用形式重写上述表达式。如何?我没能做到,但我希望一旦我做到了,就能对应用程序有更深入的了解 :-)。

最佳答案

这里要注意的非常微妙的事情是“直观地”ensure 的返回值。没关系。重要的是它是否是 JustNothing .为了表达这一点,您可以给它一个更诚实的类型签名:

ensure :: (a -> Bool) -> a -> Maybe ()
ensure p v | p v = Just ()
| otherwise = Nothing

现在,由于返回值无关紧要,您应该安全地忽略它。所以逻辑变成了这样:调用ensure (>0)ensure (<100) ,然后将它们组合在一起,忽略它们的返回值,但保留它们的 Maybe形状。

为此,您确实可以使用应用程序。您要应用的函数将执行我上面所说的:忽略两个返回值。 “保留 Maybe 形状”部分将由 Applicative 处理实例透明。所以:

let validated = (\_ _ -> x) <$> ensure (>0) x <*> ensure (<100) x

看看我应用的函数如何忽略两个参数并返回 x本身?


当然,ensure 的类型签名,正如您在问题中所写,表明它可能做的不仅仅是验证。当然,当它完全通用时它真的不能,但如果它更具体一点就可以:

ensure :: (Int -> Bool) -> Int -> Maybe Int
ensure p v | p v = Just (v + 100)
| otherwise = Nothing

现在顺序突然很重要了:

pure (-5) >>= ensure (>0) >>= ensure (<100) == Nothing
pure (-5) >>= ensure (<100) >>= ensure (>0) == Just 95

所以这里的底线是:ensure 的目的有点模棱两可。真的返回Maybe a吗?那么顺序可能很重要。是真正的返回类型 Maybe () ?然后你可以使用Applicative并忽略那些单位。

关于validation - 将 monadic 验证变成应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67473332/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com