我的问题是如何分析地处理Haskell类型签名。为了使它具体化,我正在看“修复”功能:
fix :: (a -> a) -> a
还有一个小编的功能,我写的是做Peano-ish的补充:
add = \rec a b -> if a == 0 then b else rec (a-1) (b+1)
当我检查类型时,我得到fix add
的预期类型:
fix add :: Integer -> Integer -> Integer
它似乎像我期望的那样工作:
> (fix add) 1 1
2
如何使用fix
和add
的类型签名来表明fix add
具有上述签名?什么是“代数”,如果这是正确的词,使用类型签名的规则?我怎么能“展示我的作品”?
答案 0 :(得分:8)
ghci
告诉我们
add :: Num a => (a -> a -> a) -> a -> a -> a
模拟一些类型类噪声,因为add
的第二个参数需要一个Eq
实例(你要检查它是否与0
相等)
当我们将fix
应用于add
时,fix
的签名将变为
fix :: ((a -> a -> a) -> (a -> a -> a)) -> (a -> a -> a)
请注意,a
中的fix :: (a -> a) -> a
可以包含任何类型。在这种情况下,他们的类型为(a -> a -> a)
因此fix add :: Num a => a -> a -> a
,这是添加两个a
的正确类型。
您可以以非常代数的方式使用Haskell的类型签名,变量替换的工作方式与您期望的一样。事实上,类型和代数之间存在直接的translation。