这段代码的目的是使size函数比简单地计算所有元素更有效elems.我已经决定总结构成列表的两种类型,但我似乎无法创建size函数的签名.
instance (Finite a, Finite b) => Finite (Either a b) where
elems = combineLists [Left x | x <- elems] [Right x | x <-elems]
size ??? = (size a) + (size b)
Run Code Online (Sandbox Code Playgroud)
从Prelude,我们知道Either a b = Left a | Right b.
我尝试的第一件事是匹配Either,但当然它是一种类型,所以这不起作用.接下来,我尝试过((Left a) | (Right b)),但也没有继续下去.没有其他东西似乎与这种类型相匹配Either a b.
我能够size (Left a)编译,但由于它缺少b组件,我收到错误:
Ambiguous type variable `b' in the constraint:
`Finite b' arising from a use of `size' at <interactive>:1:0-12
Run Code Online (Sandbox Code Playgroud)
这当然在上下文中有意义,但我真的不知道如何匹配Either a b.
有人有什么想法吗?
sth*_*sth 25
某种类型的东西Either a b是a Left a或a Right b,所以你有两种情况可以单独处理:
size (Left x) = size x
size (Right x) = size x
Run Code Online (Sandbox Code Playgroud)
关于模糊类型变量的错误是一个单独的问题.如果只是size (Left 1)在解释器中输入类似内容,系统就无法推断出该Left 1值的"正确"类型.它可能是,只要不知道它是什么类型,就不能检查它是否在类中(这是必需的).Either Int anythinganythingFinitesize
您可以通过指定显式类型签名来避免该问题:
size (Left 1 :: Either Int String)
Run Code Online (Sandbox Code Playgroud)