模式匹配任何2元组

时间:2019-09-06 20:14:49

标签: haskell

我想要一个函数来确定所传递的参数是否为2元组,但是以下内容无法编译。

is2Tuple :: a -> Bool
is2Tuple (_, _) = True
is2Tuple _      = False

它出现以下错误:

    • Couldn't match expected type ‘a’ with actual type ‘(a0, b0)’
      ‘a’ is a rigid type variable bound by
        the type signature for:
          isPair :: forall a. a -> Bool
        at helloworld.hs:30:1-19
    • In the pattern: (_, _)
      In an equation for ‘isPair’: isPair (_, _) = True
    • Relevant bindings include
        isPair :: a -> Bool (bound at helloworld.hs:31:1)
   |
2  | isPair (_, _) = True

有人知道为什么吗?

1 个答案:

答案 0 :(得分:7)

根据您的评论,您真正要寻找的是一种定义可以与多种参数类型一起使用的函数的方法,并且每种类型都有单独的实现。 Quote:“ 生产中的一种类型,而测试中的另一种类型”。通常称为“ 超载”。

Haskell重载函数的方法是类型类。它们有点像Java或C#中的接口,不同之处在于,您需要将它们与类型分开定义,并且编译器会自动选择所需的接口。

如果您希望函数使用两种不同的类型,并且对这些类型有不同的实现,请将此函数作为类型类的成员:

class MyClass a where
    f :: a -> String

然后为这两种类型提供此类的两个实例:

instance MyClass (a, b) where
    f (a, b) = "It's a tuple"

instance MyClass Int where
    f a = "It's an Int"

然后,编译器将能够在调用站点基于参数类型选择正确的实现:

main :: IO ()
main = do
    print (f ("foo", "bar"))  -- prints "It's a tuple"
    print (f (42 :: Int))     -- prints "It's an Int"

如果您尝试对没有实现的类型使用该函数,编译器将捕获您:

    print (f True)  -- ERROR: no instance MyClass Bool