【发布时间】:2017-07-09 22:33:56
【问题描述】:
我刚刚开始玩 Haskell(刚刚学习了绑定函数)。我喜欢它允许在 Monad 内从左到右链接后续操作的方式。
不知道有没有办法把下面的代码写得更好?
main = do
print $ Just 10
>>= (\x -> return (x*2))
>>= (\x -> return (x*3))
感觉 lambda 和 return 可以用某种部分应用的函数代替。我在想类似的事情:
(###) :: Maybe Int -> (Int -> Int) -> Maybe Int
(Just x) ### f = Just (f x)
Nothing ### f = Nothing
main = do
print $ Just 10
>>= (\x -> return (x*2))
>>= (\x -> return (x*3))
### (+3) -- the result should be (Just 63)
这当然是丑陋的、非泛型的并且不能编译:):
monads.hs:8:13:
Couldn't match expected type `a0 -> Maybe b0'
with actual type `Maybe Int'
In the second argument of `(>>=)', namely
`(\ x -> return (x * 3)) ### (+ 3)'
In the second argument of `($)', namely
`Just 10 >>= (\ x -> return (x * 2))
>>= (\ x -> return (x * 3)) ### (+ 3)'
In a stmt of a 'do' block:
print
$ Just 10 >>= (\ x -> return (x * 2))
>>= (\ x -> return (x * 3)) ### (+ 3)
monads.hs:8:14:
Couldn't match expected type `a1 -> m0 a1'
with actual type `Maybe Int'
The lambda expression `\ x -> return (x * 3)' has one argument,
but its type `Maybe Int' has none
In the first argument of `(###)', namely `(\ x -> return (x * 3))'
In the second argument of `(>>=)', namely
`(\ x -> return (x * 3)) ### (+ 3)'
无论如何,它似乎是一个有用的工具,能够在 monad 中链接一系列操作,而无需过多担心中间结果(无 do-notation),也无需明确指示代码何时回退到 Nothing。
- 是否有内置函数?
- 如果不是,我应该如何将我的
###函数更改为通用、花花公子和编译?
【问题讨论】:
-
您的
(###)本质上是翻转fmap。fmap的类型为Functor f => (a -> b) -> f a -> f b;一旦你将它专门用于Maybe,它就会变成(a -> b) -> Maybe a -> Maybe b。另请参阅this somewhat similar question。 -
请注意,
(<&>)是(###)的通用版本。
标签: haskell