Mat*_*hid 23 haskell types typeclass
许多介绍性文本将告诉您,在Haskell类型中,签名"几乎总是"可选的.任何人都可以量化"差不多"的部分吗?
据我所知,您需要显式签名的唯一时间是消除类型类的歧义.(典型的例子是read . show.)还有其他我没有想到的情况,或者是这样吗?
(我知道如果你超越Haskell 2010就有很多例外.例如,GHC永远不会推断排名N类型.但是排名N类型是语言扩展,而不是官方标准[尚未]. )
chi*_*chi 25
一般来说,多态递归需要类型注释.
f :: (a -> a) -> (a -> b) -> Int -> a -> b
f f1 g n x =
if n == (0 :: Int)
then g x
else f f1 (\z h -> g (h z)) (n-1) x f1
Run Code Online (Sandbox Code Playgroud)
(图片来源:Patrick Cousot)
注意递归调用如何看起来很糟糕(!):尽管只有四个参数,它会调用自己的五个参数!然后记住可以用实例化,这会导致出现额外的参数.fbc -> d
以上设计的例子计算
f f1 g n x = g (f1 (f1 (f1 ... (f1 x))))
Run Code Online (Sandbox Code Playgroud)
f1应用n时间在哪里.当然,编写等效程序的方法要简单得多.
Ruf*_*ind 20
如果您已MonomorphismRestriction启用,则有时您需要添加类型签名以获得最常规类型:
{-# LANGUAGE MonomorphismRestriction #-}
-- myPrint :: Show a => a -> IO ()
myPrint = print
main = do
myPrint ()
myPrint "hello"
Run Code Online (Sandbox Code Playgroud)
这将失败,因为myPrint是单态的.您需要取消注释类型签名才能使其正常工作或禁用MonomorphismRestriction.
当您将带有约束的多态值放入元组时,元组本身变为多态并具有相同的约束:
myValue :: Read a => a
myValue = read "0"
myTuple :: Read a => (a, String)
myTuple = (myValue, "hello")
Run Code Online (Sandbox Code Playgroud)
我们知道,约束影响的元组的第一部分,但并不会影响第二部分.不幸的是,类型系统并不知道,如果您尝试这样做,它会抱怨:
myString = snd myTuple
Run Code Online (Sandbox Code Playgroud)
即使直觉上人们会期望myString只是a String,类型检查器需要专门化类型变量a并确定约束是否实际上是满足的.为了使这个表达式起作用,需要注释其中的一个snd或类型myTuple:
myString = snd (myTuple :: ((), String))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1384 次 |
| 最近记录: |