如何在列表元组上定义类实例



假设我有一些类:

class Foo t where
foo :: t a -> a
bar :: t a -> a

我想定义一个这样的实例:

instance Foo ([a],[a]) where
foo = head . fst
bar = head . snd

这给了我一个错误:

main.hs:31:15: error:
• Expected kind ‘* -> *’, but ‘([a], [a])’ has kind ‘*’
• In the first argument of ‘Foo’, namely ‘([a], [a])’
In the instance declaration for ‘Foo ([a], [a])’
|
31 | instance Foo ([a],[a]) where
|  

我尝试了以下(使用TypeSynonymInstances(:

type ListFoo a = ([a],[a])
instance Foo ListFoo where
foo = head . fst
bar = head . snd

我认为newtype可以解决这个问题,但这会使实例代码变得更加复杂。有更好的方法吗?

没有办法为您指定的确切类型编写该实例,但在base中有一个同构类型,您可以在上面定义它:Product [] []:

{-# LANGUAGE FlexibleInstances #-}
import Data.Functor.Product
instance Foo (Product [] []) where
foo (Pair x _) = head x
bar (Pair _ y) = head y

您需要使用Product而不是(,)的原因是,就像您有instance Functor Maybe而不是instance Functor (Maybe a)一样,您的类型构造函数需要将类型作为参数,而不仅仅是其中有一些类型变量。

最新更新