Haskell中如何定义可返回列表或单个元素的multiApp函数?
解决multiApp函数的实现问题
先看你给出的示例:
multiApp sum [(1+), (^3), (+2)] 1 ==> 6 multiApp reverse [tail, take 2, reverse] "foo" ==> ["oof","fo","oo"]
你的初始代码逻辑是对的,但类型签名完全错误,导致编译失败。拆解下函数的执行逻辑:
- 把列表
fs里的每个函数都作用在x上,得到一个结果列表:map (\i -> i x) fs - 再把第一个参数
f作用在这个结果列表上,得到最终值
对应的正确类型逻辑是:
fs是函数列表,每个函数接收类型c的参数,返回类型a的值,即[(c -> a)]x是类型c的参数map操作后得到[a]类型的列表f是接收[a]、返回b的函数,即([a] -> b)- 最终返回值类型为
b
修正后的代码如下:
multiApp :: ([a] -> b) -> [(c -> a)] -> c -> b multiApp f fs x = f $ map (\func -> func x) fs
验证示例:
- 第一个例子:
map (\func -> func 1) [(1+), (^3), (+2)]得到[2, 1, 3],sum [2,1,3]结果为6,符合预期 - 第二个例子:
map (\func -> func "foo") [tail, take 2, reverse]得到["oo", "fo", "oof"],reverse ["oo", "fo", "oof"]结果为["oof","fo","oo"],完全匹配
你之前的类型签名(β->β) -> [(β->β)] -> β -> β错误在于,它要求f是单个值到单个值的函数,但实际f是接收列表的函数,且fs里的函数输入输出类型也不需要和f的参数类型一致,必须用多态类型适配不同场景。
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

