如何在不同类型上进行模式匹配?

Jaz*_*Man 2 haskell

data Test = [Int] | Int

foobar :: Test -> Int
Run Code Online (Sandbox Code Playgroud)

如果我想要像foobar [1,2,3] = 1和foobar 1 = 1那样的话.在erlang中它会是

foobar(X) when is_list(X) -> hd(X);
foobar(X) -> X.
Run Code Online (Sandbox Code Playgroud)

fuz*_*fuz 13

首先,您的数据声明无效.在Haskell中,您必须使用数据构造函数启动数据声明,稍后将对其进行匹配.例如,您的类型Test将被写入

data Test = TLst [Int] | TInt Int
Run Code Online (Sandbox Code Playgroud)

现在你可以简单地匹配类型构造函数; 它的字段是列表或int,具体取决于您匹配的构造函数:

foobar :: Test -> Int
foobar (TLst (x:xs)) = x
foobar (TLst [])     = error "empty list passed to foobar"
foobar (TInt x)      = x
Run Code Online (Sandbox Code Playgroud)

  • 当你说"类型构造函数"时,你的意思是"数据构造函数". (3认同)

Zop*_*opa 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
Run Code Online (Sandbox Code Playgroud)

模式匹配在这里是隐含的 - 传递给foobar的类型决定了我们选择的实例.

但是你可能不希望做这种事情,除非你的问题中存在对称性,这使得将Int和[Int]视为同类事物的两个例子是明智的.您的类型越匹配您正在解决的问题,类型检查员就越能帮助您.