如何从整体或阅读工作

asd*_*cap 1 polymorphism haskell

所述fromIntegral返回一个Num数据类型.但似乎Num能够强迫DoubleInteger没有问题.类似地,该read函数能够返回适合其类型签名所需的任何内容.这是怎么回事?如果我确实需要制作类似的功能,我该怎么做?

Non*_*ric 6

类型检查器不仅可以推断函数参数的类型,还可以推断返回类型.实际上那里没有特殊情况.如果存储结果fromIntegralreadin Integer,则将调用此类型的版本.您可以以相同的方式创建自己的功能.

例如:

class Foo a where
  foo :: a

instance Foo Integer where
  foo = 7

instance Foo String where
  foo = "Hello"

x :: Integer
x = 3

main = do
  putStrLn foo
  print (foo + x)
Run Code Online (Sandbox Code Playgroud)

因为putStrLn有类型String -> IO ()检查器发现fooin 的类型putStrLn foo必须String为程序编译.类型fooFoo a => a.因此,它推断a == String并搜索了Foo String例如.这样的实例存在并且它导致在foo :: Foo String => String那里选择值.

类似的推理发生在print (foo + x).x被称为是Integer,因为类型(+)Num a => a -> a -> a类型检查推断的加法运算符的左参数也必须是Integer这样它搜索Foo Integer实例和替代的Integer变种.

函数参数没有指向(可能的)返回类型的方向,就像在C++中一样.类型检查器甚至可以基于对函数预期返回的知识来推断函数参数.另一个例子:

twice :: a -> [a]
twice a = [a,a]

y :: [Integer]
y = twice foo
Run Code Online (Sandbox Code Playgroud)

这里的函数参数的类型Foo a => a不足以决定foo使用哪个.但是因为结果已经知道是[Integer]类型检查发现,它必须提供类型的值Integertwice并通过采用适当的实例确实如此foo.