使用具有Num和Char值的Haskell加法函数

Sup*_*M4n 10 haskell

我有以下功能的问题

sum f l1 l2 = (f l1) + (f l2)
Run Code Online (Sandbox Code Playgroud)

它不起作用sum length [1,2] ['a','b'].当我尝试这个时,我得到了

No instance for (Num Char) arising from the literal ‘1’ 
Run Code Online (Sandbox Code Playgroud)

错误,所以问题是类型.当我尝试:t功能时,我明白了sum :: Num a => (t -> a) -> t -> t -> a.因此,如果我理解正确,我不能同时使用+具有数值和字符值的函数,但我缺乏对这种情况究竟是什么以及如何解决它的更深入理解.

我尝试了几个方面,比如使用let其中一个文字或id函数,但这似乎不起作用.有帮助吗?

ber*_*gey 10

当从你的代码中推断出类型时,GHC将假设你打算f拥有一个相对简单的类型,并打算l1l2拥有相同的类型,这样两者都适合作为输入f.

你显然是想通过一个多态的f,可以同时在工作[Int][Char].根据您想要的一般情况,以下是一些选项:

在列表上f工作,无论元素类型如何,都必须在任何列表上工作:

sum0 :: (forall x. [x] -> Int) -> [a] -> [b] -> Int
sum0 f l1 l2 = f l1 + f l2
Run Code Online (Sandbox Code Playgroud)

Foldable只要两个输入都相同,就可以在列表和其他类型(矢量,设置,矩阵)上工作Foldable.第一个参数可以是length,或者特定于选择的东西Foldable,比如Set.size.

sum1 :: (Num n, Foldable f) => (forall x. f x -> n) -> f a -> f b -> n
sum1 f l1 l2 = f l1 + f l2
Run Code Online (Sandbox Code Playgroud)

允许l1l2不同 Foldable类型的. f必须适用于任何可折叠的. length仍有资格,但Set.size不够通用.

sum2 :: (Num n, Foldable s, Foldable t) => (forall f x. Foldable f => f x -> n) -> s a -> t b -> n
sum2 f l1 l2 = f l1 + f l2
Run Code Online (Sandbox Code Playgroud)

在实践中,使用这么小的函数,我认为length l1 + length l2在每个使用站点写入比在上面定义任何复杂类型的函数更容易.但很高兴知道我们可以在需要时编写这些类型.

  • @Redu应该是`RankNTypes`,我很确定. (2认同)