是否可以在Haskell中定义一个具有两种可能类型的输入参数的函数?

use*_*425 3 haskell pattern-matching parametric-polymorphism

为了我自己的理解,我想在Haskell中定义一个带有两个参数的函数 - 无论是整数还是两个Chars.它对参数做了一些微不足道的检查,如下:

foo 1 2 = 1
foo 2 1 = 0
foo 'a' 'b' = -1
foo _ _ = -10
Run Code Online (Sandbox Code Playgroud)

我知道这不会编译,因为它不知道它的args是Num还是Char类型.但我无法使其论证具有多态性,例如:

foo :: a -> a -> Int
Run Code Online (Sandbox Code Playgroud)

因为那时我们说它必须是身体中的Char(或Int).

是否可以在Haskell中执行此操作?我想过可能会创建一个自定义类型?就像是:

data Bar = Int | Char
foo :: Bar -> Bar -> Int
Run Code Online (Sandbox Code Playgroud)

但我认为这也不合适.一般来说,我很困惑Haskell中的函数是明确的ONE类型,还是类型类的多态,是否禁止在函数体中使用特定类型.

Sib*_*ibi 5

您可以使用Either数据类型存储两种不同的类型.这样的事情应该有效:

foo :: Either (Int, Int) (Char, Char) -> Int
foo (Right x) = 3
foo (Left y) = fst y
Run Code Online (Sandbox Code Playgroud)

因此,对于它的Left数据构造函数,您将两个传递Int给它,对于它的Right构造函数,您将两个传递Char给它.另一种方法是定义你自己的algebric数据类型,如下所示:

data MyIntChar = MyInt (Int, Int) | MyChar (Char, Char) deriving (Show)
Run Code Online (Sandbox Code Playgroud)

如果你观察,那么你可以看到上面的类型与Either数据类型是同构的.


Dan*_*ner 5

我不确定我是否一定会建议使用类型类,但它们至少可以做到这样的事情.

class Foo a where
    foo :: a -> a -> Int

instance Foo Int where
    foo 1 2 = 1
    foo 2 1 = 0
    foo _ _ = -10

instance Foo Char where
    foo 'a' 'b' = -1
    foo _ _ = -10
Run Code Online (Sandbox Code Playgroud)