我正试图做一项任务,但是当我试图这样做时:
data Fruit = Pear | Orange | Apple | Banana
data Colour = Red | Orange | Yellow | Green
我得到一个错误。有什么问题吗?为什么我不能两次使用Orange
?
注释已经讨论了诸如"编译器以后不会知道你指的是哪一个"one_answers"不允许Haskell推断类型"之类的问题。
但在最基本的情况下,这与您编写像 这样的代码时遇到的问题是一样的x :: Int
x = 4
x = 9
或者,在类c语言中
void foo() {
printf("this");
}
void foo() {
printf("that");
}
-在所有这些例子中,你两次定义了相同名称的东西,但做了不同的事情。具体来说,使用两个都称为Orange
的构造函数,您可以在底层定义以下所有内容:
data Fruit = Fruit0 | Fruit1 | Fruit2 | Fruit3
pear, orange, apple, banana :: Fruit
pear = Fruit0
orange = Fruit1
apple = Fruit2
banana = Fruit3
data Colour = Colour0 | Colour1 | Colour2 | Colour3
red, orange, yellow, green :: Colour
red = Colour0
orange = Colour1
yellow = Colour2
green = Colour3
(甚至更多,因为构造函数也可以通过模式匹配de构造)
更有趣的问题是:为什么其他语言允许你写这样的东西?
struct Fruit {
peariness, orangeness, appleness, banananess :: Float
};
struct Colour {
redness, orangeness, yellowness, greenness :: Float
};
这里发生的事情是OO语言中的结构/类同时声明一个新类型和一个新的命名空间。Fruit
类中的orangeness
只是Fruit/orangeness
(或c++语法中的Fruit::orangeness
)的不限定形式。
Haskell也有命名空间,但是只以模块的形式出现。(在三个独立的文件中)
是完全可以的module Fruit where
data Fruit = Pear | Orange | Apple | Banana
deriving (Show)
module Colour where
data Colour = Red | Orange | Yellow | Green
deriving (Show)
module Main where
main :: IO ()
main = do
print Fruit.Orange
print Colour.Orange