lil*_*zek 1 haskell type-inference
我是Haskell世界的新手,所以这可能是一个基本问题.
这段代码可以:
data Numero =
Integer Integer |
Rational Rational |
Double Double
deriving (Show)
data Elemento =
Numero Numero |
Incognita String
deriving (Show)
data Monomio = Monomio {base :: Elemento, exp :: Numero} deriving(Show)
main = print (Monomio (Numero (Integer 15)) (Integer 20))
Run Code Online (Sandbox Code Playgroud)
在没有明确类型的情况下表达:
(Monomio (Numero (Integer 15)) (Integer 20))
Run Code Online (Sandbox Code Playgroud)
?
这个表达式:
main = print (Monomio (Integer 15) (Integer 20))
Run Code Online (Sandbox Code Playgroud)
更短的是不明确的,因为(整数15)不能适合(Incognita字符串)的定义,但它不编译:
main.hs:13:24:
Couldn't match expected type `Elemento' with actual type `Numero'
In the first argument of `Monomio', namely `(Integer 15)'
In the first argument of `print', namely
`(Monomio (Integer 15) (Integer 20))'
Run Code Online (Sandbox Code Playgroud)
为什么?
该Numero表达式中的
(Monomio (Numero (Integer 15)) (Integer 20))
Run Code Online (Sandbox Code Playgroud)
是不是一个类型-但一个类型值构造,所以你需要它,以构建一些类型的值Elemento.
一种方法是使用fromIntegral以实现"自动"转换.
对于String-like你有OverloadedStrings-Language扩展,但是对于数字类型,没有类似的东西(至少据我所知).
旁注:我认为它使您的代码更加混乱,因为您有一种类型Numero和类型构造函数,Numero后者构造类型的东西Elemento.
我会用NumElemento和VarElemento什么等.
一种更简洁但完全不同的方法(如我的评论所述),将使用多项式而不是单体.
data Polynomial1 = P1 String [Rational]
newtype Polynomial = P [Polynomial1]
Run Code Online (Sandbox Code Playgroud)
这里P1 "X" [1,2,3]代表p(x) = 1 + 2*x + 3*x²和P [P1 "X" [1,2], P1 "Y" [0,1]]支持p(x,y) = 1 + 2*x + y
这种方法解决了许多发生的问题,如果你小心你甚至可以代表泰勒系列(除非你没有检查你没有检查cosine == cosine- 虽然显然是真的,你碰巧在无限的比较过程中运行).