具有复合/多参数类型构造函数的Haskell类型签名
我发现了这些类型的签名:具有复合/多参数类型构造函数的Haskell类型签名,haskell,types,polymorphism,Haskell,Types,Polymorphism,我发现了这些类型的签名: x :: a b -> Int x f = 3 y :: a b c -> Int y f = 3 z :: a b c d -> Int z f = 3 > x [1] -- 3 > y (1, 2) -- 3 > z (1, 2, 3) -- 3 基本上: x只接受包含1个或多个参数的类型构造函数中的值 y只接受包含2个或更多参数的类型构造函数中的值 z只接受包含3个或更多参数的类型构造函数中的值 它们是有效的,但我不确定
x :: a b -> Int
x f = 3
y :: a b c -> Int
y f = 3
z :: a b c d -> Int
z f = 3
> x [1] -- 3
> y (1, 2) -- 3
> z (1, 2, 3) -- 3
基本上:
它们似乎与多类型概念或类型构造函数上的多态性有关,但基于类型构造函数接受的许多参数强制执行不变量。如果没有进一步的约束,这些类型是无用的–除了直接传递它们之外,您真的无法处理它们。但签名
a->Int
的情况实际上也是如此:如果对a
一无所知,那么你也无能为力
但是,与例如toInteger::Integral a=>a->Integer
一样,向参数添加约束可以让您完成一些事情。比如说,
import Data.Foldable
import Prelude hiding (foldr)
x' :: (Foldable a, Integral b) => a b -> Integer
x' = foldr ((+) . toInteger) 0
通常情况下,当你们有一种形式
abb。。。没有p q
,然后a b。。。p
至少是Functor
类的一个实例,通常也是Applicative
和Monad
;有时可折叠
,可遍历
,或Comonad
;有时a b。。。o
将是箭头
。。。这些约束允许您在不知道您正在处理的特定类型构造函数的情况下大量处理复合类型。在研究@leftaroundabout answer并在GHCI中进行实验后,我对复合类型有了一个了解。它们与应用类型的统一基于求值顺序及其类型变量的种类签名。评估顺序非常重要,因为abc~((a)b)c)
而a(bc)
是(a((b)c)
。这使得abc
匹配组合类型,其中a
与类型构造函数*->*->*
匹配,而abc
与*->*
和abc
与*
匹配
我在本文中用图表和GHCI代码对其进行了充分的解释()(对于堆栈溢出来说太长了)谢谢!这是有道理的,但您能否解释一下为什么
ab
适用于1个或更多参数的类型构造函数,而ab c
适用于2个或更多参数的类型构造函数。(重点是更多)它怎么知道额外的参数仍然满足类型规则呢?呃…它不起作用,不是说你可以写签名,比如说,或者Int->String
:函数的每个参数/结果都必须有kind*
,但是或者Int:*->*
。那么…你是什么意思?好的,让这更清楚一点我很困惑到底什么是abc
。它是abc
还是abc
?它是如何选择的?此外,像fn::(tcb)=>abint
这样的签名接受(1,X)
和(1,2,X)
和(“字符串”,“字符串”,“字符串”,“字符串”,X)
只要X受TC约束。为什么所有这些类型都有效?我在GHCI中尝试过,我可以继续运行fn blah
其中blah是我上面写的所有类型。另外,我不理解你最后一段“通常情况下……”嗯,类型的解析方式与表达式完全相同,即abc
表示(ab)c
,也就是说,a
实际上不是两种类型参数的函数:它是curry–一种类型变量的函数,产生另一种类型参数的函数,产生一种类型。因此AB c
只是DC
的一个特例,带有d~AB
;特别是,(Int,Int,a)~(,)Int Int a~ta
与t~(Int,Int,)
。