data Test = [Int] | Int
foobar :: Test -> Int
如果我想要像foobar [1,2,3] = 1和foobar 1 = 1这样的东西怎么办?在erlang中它会是
foobar(X) when is_list(X) -> hd(X);
foobar(X) -> X.
答案 0 :(得分:13)
首先,您的数据声明无效。在Haskell中,您必须使用数据构造函数启动数据声明,稍后将对其进行匹配。例如,您的类型Test
将被写入
data Test = TLst [Int] | TInt Int
现在你可以简单地匹配类型构造函数;它的字段是列表或int,具体取决于您匹配的构造函数:
foobar :: Test -> Int
foobar (TLst (x:xs)) = x
foobar (TLst []) = error "empty list passed to foobar"
foobar (TInt x) = x
答案 1 :(得分:7)
另一种方法是使用类型类,如下所示:
class Test a where
foobar a -> Int
instance Test Int where
foobar x = x
instance Test [Int] where
foobar [] = error "Empty list"
foobar (x:_) = x
模式匹配在这里是隐式的 - 传递给foobar的类型决定了我们选择的实例。
但你可能不希望做这种事情,除非你的问题中存在对称性,这使得将Int和[Int]视为同类事物的两个例子是明智的。你的类型越匹配你正在解决的问题,类型检查员就越能帮助你。
答案 2 :(得分:3)
首先,这不是有效的Haskell语法:
data Test = [Int] | Int -- this doesn't work
替代方案需要自己的构造函数。所以这是有效的:
data Test = TestA [Int] | TestB Int
然后你可以像这样模式匹配:
foobar :: Test -> Int
foobar (TestA listOfInt) = length listOfInt
foobar (TestB int) = int