gpt4 book ai didi

haskell - 将多态函数应用于两种不同类型的输入

转载 作者:行者123 更新时间:2023-12-04 19:26:40 25 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Haskell: How to create most generic function possible that applies a function to tuple items

(2 个回答)


2年前关闭。




考虑这个函数:

doToBoth f x y = (f x, f y)

它在简单情况下按预期工作:
doToBoth (2 *) 10 15 == (20, 30)
doToBoth head [1,2] [3,4,5] == (1, 3)

然后我尝试了这些:
doToBoth head [1,10,100] "apple"
doToBoth pred 2 'b'

我希望它们都产生 (1, 'a') ,但它们只会导致类型错误。问题在于 doToBoth 的推断类型不够多态:
doToBoth :: (a1 -> a2) -> a1 -> a1 -> (a2, a2)

看到这一点,我尝试添加一个显式类型签名来修复它:
doToBoth :: (t ~ (i1 -> o1), t ~ (i2 -> o2)) => t -> i1 -> i2 -> (o1, o2)

这种类型签名被接受,但它没有解决问题,并检查发生了什么 :t doToBoth揭示它最终得到了一种与原始推断出的类型等效的类型:
doToBoth :: (i2 -> o2) -> i2 -> i2 -> (o2, o2)

编写类型签名以使此函数按我想要的方式工作的正确方法是什么?

最佳答案

接受一个多态参数会使你的函数 rank-2 多态。 GHC有an extension for that ,但只有当你能以某种方式量化参数必须支持的类型时,你才能使用它 - 使用类型构造函数或 -classes。例如,对于列表,您可以编写

{-# LANGUAGE Rank2Types, UnicodeSyntax #-}
doToBoth_listelem :: (∀ x . [x] -> x) -> [a] -> [b] -> (a,b)
doToBoth_listelem f x y = (f x, f y)
> doToBoth_listelem head [1,10,100] "apple"
(1,'a')

这也适用于 pred例如,并且更有用一些。在这种情况下,您需要对受 Enum 约束的参数进行量化。类(class):
doToBoth_enum :: (Enum a, Enum b)
=> (∀ x . Enum x => x -> x) -> a -> b -> (a,b)
doToBoth_enum f x y = (f x, f y)
> doToBoth_enum pred 2 'b'
(1,'a')

编写它以便它自动适用于参数可能需要的任何此类约束,我认为,这是不可能的。也许可以用一些巧妙的类型系列和约束类型来近似它,但我怀疑它最终会实际可用。

关于haskell - 将多态函数应用于两种不同类型的输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54137973/

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