【发布时间】:2016-10-27 15:13:32
【问题描述】:
我有这三个功能
a :: Int -> Maybe Int
a i = if i < 100 then Just i else Nothing
b :: Int -> Maybe Int
b i = if i < 50 then Just i else Nothing
c :: Int -> Maybe Int
c i = if i > 0 then Just i else Nothing
我想将它们链接在一起,以便当一个函数的结果导致 Nothing 时,返回该函数的输入。
我可以用这个功能实现:
import Data.Maybe (fromMaybe)
e :: Int -> [Int -> Maybe Int] -> Int
e i [] = i
e i (f:fs) = e (fromMaybe i $ f i) fs
-
*Main> e 75 [a,b,c]
75
在基础库中是否存在表现出这种行为的现有函数、Monad 实例或其他方式?
【问题讨论】:
-
应该清楚,一般情况下不能这样做,因为输入和输出类型可能不同。您可以编写
(a -> Maybe a) -> a -> a类型的函数,但不能编写(a -> Maybe b) -> a -> b -
我首先像你一样使用
fromMaybe将[Int -> Maybe Int]变成[Int -> Int]。之后,我将组成 endos 列表。 -
foldr1 (>=>) [a, b, c] -
@AlexanderVoidExRuchkin 这与
\i -> e i [a,b,c]的语义不同(其中e在上面的问题中定义)。 -
e = fromMaybe 75 . foldr1 (>=>) [a,b,c],不过。