我是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))
在没有明确类型的情况下表达:
(Monomio (Numero (Integer 15)) (Integer 20))
这个表达式:
main = print (Monomio (Integer 15) (Integer 20))
更短是不明确的,因为(整数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))'
为什么?
答案 0 :(得分:5)
表达式中的Numero
(Monomio (Numero (Integer 15)) (Integer 20))
不是类型 - 而是类型值构造函数,因此您需要它来构造某事类型为Elemento
的值。
一种方法是使用fromIntegral
来实现"自动"转换。
对于String
- 就像你有OverloadedStrings
- 语言扩展,但对于数字类型,没有类似的东西(至少据我所知)。
旁注:我认为这会使您的代码更加混乱,因为您有Numero
类型和Numero
类型构造函数,后者构造类型为{{1}的类型}}
我会使用Elemento
和NumElemento
之类的东西。
更简洁但完全不同的方法(如我的评论中所述),将使用多项式而不是单体。
VarElemento
此处data Polynomial1 = P1 String [Rational]
newtype Polynomial = P [Polynomial1]
代表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
- 尽管显然是真的,你碰巧在一个无限的比较过程)。