繁体   English   中英

如何为具有两个参数的类型创建仿函数实例,其中两个参数必须为同一类型?

[英]How do I create a functor instance for a type with two arguments, where both arguments have to be the same type?

我几乎可以为Pair类型创建有效的仿函数实例。 问题是,Pair接受两个相同类型的参数,所以当我写

fmap f (Pair a a') = Pair a (f a')

我不能保证结果是有效的对,因为(f a')可以是任何类型。

确保此约束的Haskell方法是什么?

import Test.QuickCheck
import Test.QuickCheck.Function

data Pair a = Pair a a deriving (Eq, Show)

instance Functor Pair where
  fmap f (Pair a a') = Pair a (f a')

-- stuff below just related to quickchecking that functor instance is valid
main = quickCheck (functorCompose' :: PFC)

type P2P = Fun Int Int

type PFC = (Pair Int) -> P2P -> P2P -> Bool

instance (Arbitrary a) => Arbitrary (Pair a) where
  arbitrary = do
    a <- arbitrary
    b <- arbitrary
    return (Pair a b)

functorIdentity :: (Functor f, Eq (f a)) => f a -> Bool
functorIdentity f = fmap id f == f

functorCompose :: (Eq (f c), Functor f) => (a -> b) -> (b -> c) -> f a -> Bool
functorCompose f g x = (fmap g (fmap f x)) == (fmap (g . f) x)

functorCompose' :: (Eq (f c), Functor f) => f a -> Fun a b -> Fun b c -> Bool
functorCompose' x (Fun _ f) (Fun _ g) = (fmap (g . f) x) == (fmap g . fmap f $ x)

这是我收到的错误消息,顺便说一句:

chap16/functor_pair.hs:22:29: Couldn't match expected type ‘b’ with actual type ‘a’ …
      ‘a’ is a rigid type variable bound by
          the type signature for fmap :: (a -> b) -> Pair a -> Pair b
          at /Users/ebs/code/haskell/book/chap16/functor_pair.hs:22:3
      ‘b’ is a rigid type variable bound by
          the type signature for fmap :: (a -> b) -> Pair a -> Pair b
          at /Users/ebs/code/haskell/book/chap16/functor_pair.hs:22:3
    Relevant bindings include
      a' :: a
        (bound at /Users/ebs/code/haskell/book/chap16/functor_pair.hs:22:18)
      a :: a
        (bound at /Users/ebs/code/haskell/book/chap16/functor_pair.hs:22:16)
      f :: a -> b
        (bound at /Users/ebs/code/haskell/book/chap16/functor_pair.hs:22:8)
      fmap :: (a -> b) -> Pair a -> Pair b
        (bound at /Users/ebs/code/haskell/book/chap16/functor_pair.hs:22:3)
    In the first argument of ‘Pair’, namely ‘a’
    In the expression: Pair a (f a')
Compilation failed.

(这是来自http://haskellbook.com/的练习)

假设f :: t1 -> t2 我们想要fmap f :: Pair t1 -> Pair t2 您的尝试是:

fmap f (Pair a a') = Pair a (f a')
                       -- ^

这是错误类型的,因为a是类型t1而不是类型t2

如果只有能够将t1值转换为t2值的东西,我们可以简单地在a上使用它,并且所有内容都会键入check。 我们有这样的东西吗? ;-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM