作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个类型为 Integral => a -> a -> Maybe a
的函数 f
。这意味着
f 1 2
是有效的代码,但是自然的组合,例如
f (f 3 4) 5
f 6 (f 7 8)
f (f 9 10) (f 11 12)
无效。
有一些方法可以让它发挥作用。例如,
f 6 =<< f 7 8
这是我所知道的对于案例 2 最好的方法。对于案例 3,
join $ f <$> f 9 10 <*> f 11 12
是我能想到的最好的,但额外的 join
却显得很突出。我对情况 1 没有什么好主意。除此之外,令我困扰的是我想出的语法并不“一致”——我基本上完成了相同的事情,但语法非常不同。
是否有一个标准/惯用的结构允许我将 f
转换为 Maybe a -> a -> Maybe a
, a -> Maybe a -> Maybe a
和 Maybe a -> Maybe a -> Maybe a
,具有良好且一致的语法?
最佳答案
让我们为第一种情况创建一个实用函数:
lift :: (a -> b -> Maybe c) -> Maybe a -> b -> Maybe c
lift _ Nothing _ = Nothing
lift f (Just a) b = f a b
情况1:
lift f (f 3 4) 5
情况2:
f 6 =<< f 7 8
情况3:
lift f (f 9 10) =<< f 11 12
虽然它看起来更一致,但以我的拙见,它仍然看起来很丑。也许其他人可以提供更好的解决方案。
编辑:在思考我的解决方案后,我意识到它可以推广:
(<&>) :: (Applicative m, Monad m) => m (a -> m b) -> m a -> m b
f <&> a = join $ f <*> a
infixl 4 <&>
情况1:
f <$> f 3 4 <&> pure 5
情况2:
f <$> pure 6 <&> f 7 8
情况3:
f <$> f 9 10 <&> f 11 12
这适用于任意数量的函数:
f <$> a <&> b -- f :: a -> a -> Maybe a
f <$> a <*> b <&> c -- f :: a -> a -> a -> Maybe a
f <$> a <*> b <*> c <&> d -- f :: a -> a -> a -> a -> Maybe a
等等......
编辑:我
同意
@n.m。最好的解决方案是将函数的类型签名更改为 Maybe a -> Maybe a -> Maybe a
并在必要时使用 Just
。
情况1:
f (f (Just 3) (Just 4)) (Just 5)
情况2:
f (Just 6) (f (Just 7) (Just 8))
情况3:
f (f (Just 9) (Just 10)) (f (Just 11) (Just 12))
最简单的解决方案总是最好的。
编辑:实际上,回想起来,我以前的解决方案要简单得多。
关于haskell - 转换 a -> a -> Maybe a 以采用 a 和 Maybe a 的任意组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26520261/
我是一名优秀的程序员,十分优秀!