如何在Haskell中为此类创建实例?

问题描述 投票:2回答:1

我一直在阅读《学习Haskell时我希望知道什么》一书,在这个示例中我停了下来:

class Bifunctor p where
    bimap  :: (a -> b) -> (c -> d) -> p a c -> p b d
    first  :: (a -> b) -> p a c -> p b c
    second :: (b -> c) -> p a b -> p a c

我的问题是:如何创建该类的实例?想法是将该函数调用为:

λ bimap  (+1) (+2) (8, 9) -- (9, 11)
λ first  (*4) (10, 8) -- (40, 8)
λ second (*2) (3, 5) -- (3, 10)

我最接近完成此任务的是:

instance Bifunctor (x, y) where
    bimap func func' (x, y) = (func x, func' y)
    first func (x, y) = (func x, y)
    second func (x, y) = (x, func y)

但是它不起作用,它会引发一个错误:

• Expecting two fewer arguments to ‘(x, y)’
  Expected kind ‘* -> * -> *’, but ‘(x, y)’ has kind ‘*’
• In the first argument of ‘Bifunctor’, namely ‘(x, y)’
  In the instance declaration for ‘Bifunctor (x, y)’
haskell typeclass
1个回答
0
投票

(x,y)已经是一个具体的元组类型,包含两个具体的(尽管未知)类型xy。同时,函子或bifunctor应该是parametric,即,在元组实例的情况下,您希望将所包含的类型保留为参数,然后在输入时将它们填充为各种不同的具体类型。使用方法。

即,您基本上想要一个type-level lambda

instance Bifunctor (\x y -> (x, y)) where

嗯,Haskell没有类型级别的lambda,但是在类型级别上确实有部分应用程序–在这种情况下甚至没有partial,您不想将元​​组构造函数应用于任何类型< [全部,但只需打开它们即可。这样写:

instance Bifunctor (,) where
如果您只想将其应用于一个参数,则编写

instance Functor ((,) a) where

如果将其解析为Functor (a,),我会更容易理解-但这在Haskell中实际上并不合法。    
© www.soinside.com 2019 - 2024. All rights reserved.