Reputation: 1195
I want a function deciding if the passed argument is a 2-tuple, but the following does not compile.
is2Tuple :: a -> Bool
is2Tuple (_, _) = True
is2Tuple _ = False
It gives the following error:
• 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
Anyone knows why?
Upvotes: 0
Views: 112
Reputation: 80744
Based on your comments, what you're really looking for is a way to define a function that works with several parameter types, and has separate implementations for each type. Quote: "one type in production and another type in testing". This is usually called "overloading".
The way to overload functions is Haskell is type classes. They are somewhat like interfaces in Java or C#, except you get to define them separately from the types, and the compiler picks the one you need automatically.
If you want your function to work with two different types, and have different implementations for those types, make this function a member of a type class:
class MyClass a where
f :: a -> String
And then provide two instances of this class for the two types:
instance MyClass (a, b) where
f (a, b) = "It's a tuple"
instance MyClass Int where
f a = "It's an Int"
Then the compiler will be able to pick the right implementation based on paramater types at call sites:
main :: IO ()
main = do
print (f ("foo", "bar")) -- prints "It's a tuple"
print (f (42 :: Int)) -- prints "It's an Int"
It you try to use the function with a type for which there is no implementation, the compiler will catch you:
print (f True) -- ERROR: no instance MyClass Bool
Upvotes: 7