haskell - 具有可能多态参数的函数的类型签名

标签 haskell

我可以,如果可以,我该如何为函数编写类型签名:

g f x y = (f x, f y)

这样给出:
f1 :: a -> [a]
f1 x = [x]

x1 :: Int
x1 = 42

c1 :: Char
c1 = 'c'

f2 :: Int -> Int
f2 x = 3 * x

x2 :: Int
x2 = 5

这样:
g f1 x1 c1 == ([42], ['c']) :: ([Int], [Char])
g f2 x1 x2 == (126, 15) :: (Int, Int)

最佳答案

不,你不能。基本问题是 Haskell 的语法让你误以为 f1的和 f2的类型比实际情况更相似。一旦翻译成 GHC Core,它们看起来就大不相同了:

f1 :: forall a . a -> [a]
f2 :: Int -> Int
不仅如此,相应的术语看起来也大不相同:
f1 = Λa -> λ(x :: a) -> [x]
f2 = λ(x :: Int) -> 3 * x
如您所见,f1f2实际上有不同数量的参数,其中 f1接受一个类型和一个值,f2只取一个值。
在更常见的情况下,当你扑通f1进入期望类型函数的上下文,例如 Int -> [Int] , GHC 将申请f1为您所需的类型(即,将 f1 实例化为特定类型),一切都会好起来的。例如,如果您有
g :: (Int -> [Int]) -> Bool
你申请gf1 , GHC 实际上会将其编译为
g (f1 @Int)
但是在这里,您需要关于该实例化是否发生的多态性,这是 GHC 不支持的(我认为这将是对核心语言的一个相当激进和破坏性的改变)。
由于类实例、类型族模式和类型族结果无法量化,我非常有信心没有办法得到你想要的。

关于haskell - 具有可能多态参数的函数的类型签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38603014/

相关文章:

haskell - GHC 源代码 "zonk"是什么意思?

haskell - 单独使用的括号 () 是什么意思?

haskell - 有没有更好的方法来用无点符号表示绝对误差函数?

haskell - IO 字符串列表

haskell - 在 macOS 上构建堆栈

list - 将我自己类型的项目添加到 Haskell 的列表中?

haskell - 语法 $$ 在 Haskell 中是什么意思?

haskell - 为什么 (*3) `map` (+100) 在 Idris 中不起作用?

haskell - 非纯函数式语言 OCaml 出现 'let rec' 的原因是什么?

haskell - 如何在 Haskell 中表示这种类型