Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell fromIntegral或read是如何工作的_Haskell_Polymorphism - Fatal编程技术网

Haskell fromIntegral或read是如何工作的

Haskell fromIntegral或read是如何工作的,haskell,polymorphism,Haskell,Polymorphism,fromIntegral返回一个Num数据类型。但似乎Num能够强制执行Double或Integer而没有问题。类似地,read函数能够返回符合其类型签名所需的任何内容。这是怎么回事?如果我真的需要做一个类似的函数,我该怎么做呢?类型检查器不仅可以推断函数参数的类型,还可以推断返回类型。事实上,那里没有特殊情况。如果在Integer中存储integral或read的结果,将调用此类型的版本。您可以用同样的方法创建自己的函数 例如: class Foo a where foo :: a in

fromIntegral
返回一个
Num
数据类型。但似乎
Num
能够强制执行
Double
Integer
而没有问题。类似地,
read
函数能够返回符合其类型签名所需的任何内容。这是怎么回事?如果我真的需要做一个类似的函数,我该怎么做呢?

类型检查器不仅可以推断函数参数的类型,还可以推断返回类型。事实上,那里没有特殊情况。如果在
Integer
中存储integral或
read
结果,将调用此类型的版本。您可以用同样的方法创建自己的函数

例如:

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)
twice :: a -> [a]
twice a = [a,a]

y :: [Integer]
y = twice foo
因为
putStrLn
具有类型
String->IO()
类型检查器发现
putStrLn foo
中的
foo
类型必须是
String
,程序才能编译。
foo
的类型是
fooa=>a
。因此它推断出
a==String
并搜索
foostring
实例。这样的实例存在,它会导致在那里选择
foo::foo String=>String

类似的推理发生在
print(foo+x)
x
已知为
Integer
,并且由于
(+)
的类型为
Num a=>a->a->a
类型检查器推断加法运算符的左参数也必须是
Integer
,因此它搜索
Foo Integer
实例并替换
Integer
变量

<> C++中没有函数指令到(可能)返回类型的方向。类型检查器甚至可以根据函数预期返回的内容推断函数参数。另一个例子:

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)
twice :: a -> [a]
twice a = [a,a]

y :: [Integer]
y = twice foo

这里的函数参数的类型是
fooa=>a
,它不足以决定使用哪个
Foo
。但是,由于已知结果是
[Integer]
,类型检查器发现它必须向
提供两次
Integer
类型的值,并且通过使用
foo

的适当实例,类型检查器不仅能够推断函数参数的类型,而且能够推断返回类型。事实上,那里没有特殊情况。如果在
Integer
中存储integral
read
结果,将调用此类型的版本。您可以用同样的方法创建自己的函数

例如:

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)
twice :: a -> [a]
twice a = [a,a]

y :: [Integer]
y = twice foo
因为
putStrLn
具有类型
String->IO()
类型检查器发现
putStrLn foo
中的
foo
类型必须是
String
,程序才能编译。
foo
的类型是
fooa=>a
。因此它推断出
a==String
并搜索
foostring
实例。这样的实例存在,它会导致在那里选择
foo::foo String=>String

类似的推理发生在
print(foo+x)
x
已知为
Integer
,并且由于
(+)
的类型为
Num a=>a->a->a
类型检查器推断加法运算符的左参数也必须是
Integer
,因此它搜索
Foo Integer
实例并替换
Integer
变量

<> C++中没有函数指令到(可能)返回类型的方向。类型检查器甚至可以根据函数预期返回的内容推断函数参数。另一个例子:

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)
twice :: a -> [a]
twice a = [a,a]

y :: [Integer]
y = twice foo

这里的函数参数的类型是
fooa=>a
,它不足以决定使用哪个
Foo
。但因为已知结果是
[Integer]
类型检查器发现它必须向
提供两次
整型
值,并通过使用
foo
的适当实例来执行此操作。read
是的成员,这意味着它的实现可以依赖于类型参数

此外,像
1
42
等数字文字是函数调用
fromInteger 1
fromInteger 42
等的语法糖类,而
fromInteger
本身是Num typeclass的成员


因此,文本
42
(或
from integer 42
)可以返回
Int
Double
或任何其他Num实例,具体取决于调用它的上下文。

read
是的成员,这意味着它的实现可以依赖于类型参数

此外,像
1
42
等数字文字是函数调用
fromInteger 1
fromInteger 42
等的语法糖类,而
fromInteger
本身是Num typeclass的成员


因此,文本
42
(或
from integer 42
)可以返回
Int
Double
或任何其他Num实例,具体取决于调用它的上下文。

我对这里的术语有点挑剔,因为我觉得你说的这些话暴露了你对Haskell工作原理的误解

fromIntegral返回Num数据类型

更准确地说,
fromIntegral
将具有
类Integral
实例的任何类型作为输入,并可以返回属于
类Num
实例的任何类型。前奏曲对它的定义如下:

fromIntegral :: (Integral a, Num b) => a -> b
fromIntegral = fromInteger . toInteger
带有
Integral
实例的类型实现
toInteger
函数,所有带有
Num
实例的类型实现
fromInteger
fromIntegral
使用与
Integral a
实例关联的
toInteger
a
类型的值转换为整数。然后它使用<