Haskell: 创建函数实例

Haskell: create Function instance

我目前正在从非常棒的 Haskell from first principles, and while trying to check the functor instances for each datatype using QuickCheck, I've stumbled against a mayor problem creating a Function 实例中学习 Haskell 我的 Four 数据类型:

data Four' a b = Four' a a a b deriving (Eq,Show)
instance Function (Four' a b) where
  function =  let
                  injection :: (Function a, Function b) => (Four' a b) -> (a,a,a,b)
                  injection (Four' x1 x2 x3 z1) = (x1,x2,x3,z1)
                  surjection :: (Function a, Function b) => (a,a,a,b) -> (Four' a b)
                  surjection (x1,x2,x3,z1) = (Four' x1 x2 x3 z1)
              in functionMap injection surjection

会引发以下错误:

Error: • No instance for (Function a) arising from a use of ‘functionMap’
  Possible fix:
    add (Function a) to the context of
      the type signature for:
        function :: forall b1. (Four' a b -> b1) -> Four' a b :-> b1
      or the instance declaration
• In the expression: functionMap injection surjection

此外,尝试创建 Function 实例和 Arbitrary 实例(如果它们都生成函数)之间究竟有什么区别?

我怀疑这是否真的是您想要的。对需要 Function 的您正在尝试做的事情的一些解释将帮助我们判断是否是这种情况。

但是为了回答已经存在的技术问题,Function(和 CoArbitrary,如果您确实需要 Function,您也将需要它)具有默认的通用实现,所以您无需执行或了解任何内容。

  1. 导出Generic
  2. 写入 FunctionCoArbitrary
  3. 的空实例
{-# LANGUAGE DeriveGeneric #-}

import GHC.Generics (Generic)
import Test.QuickCheck

data Four a b = ... deriving (Eq, Show, Generic)  -- Derive generic

-- Default implementations
instance (Function a, Function b) => Function (Four a b)
instance (CoArbitrary a, CoArbitrary b) => CoArbitrary (Four a b)

Also,what is exactly the difference between trying to create a Function instance and an arbitrary instance if they both generate functions?

  • Arbitrary a: "how to generate and shrink values of type a"
  • CoArbitrary a+Function a: "how to generate and shrink values of type a -> b (for suitably constrained b)"

这些不一样。