任意类型类约束中的非类型变量参数

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

对于Haskell Programming From First Principles的第15章中的练习,我正在尝试编写基于另一个Arbitrary实例的Arbitrary实例:

module AccumulateRight where

import Data.Semigroup
import Test.QuickCheck

data Validation a b = Fail a | Pass b deriving (Eq, Show)

newtype AccumulateRight a b =
    AccumulateRight (Validation a b) deriving (Eq, Show)

type TestType = AccumulateRight String [Int]

instance Semigroup b => Semigroup (AccumulateRight a b) where
    _ <> (AccumulateRight (Fail x)) = Fail x
    (AccumulateRight (Fail x)) <> _ = Fail x
    (AccumulateRight (Success a)) <> (AccumulateRight (Success b)) =
        AccumulateRight . Success $ a <> b

instance (Arbitrary a, Arbitrary b) => Arbitrary (Validation a b) where
    arbitrary = oneof [Fail <$> arbitrary, Pass <$> arbitrary]

instance Arbitrary (Validation a b) => Arbitrary (AccumulateRight a b) where
    arbitrary = AccumulateRight <$> arbitrary

semigroupAssoc :: (Eq m, Semigroup m) => m -> m -> m -> Bool
semigroupAssoc a b c = (a <> (b <> c)) == ((a <> b) <> c)

type Assoc = TestType -> TestType -> TestType -> Bool

main :: IO ()
main = quickCheck (semigroupAssoc :: Assoc)

但发生以下错误:

    • Non type-variable argument
        in the constraint: Arbitrary (Validation a b)
      (Use FlexibleContexts to permit this)
    • In the context: Arbitrary (Validation a b)
      While checking an instance declaration
      In the instance declaration for ‘Arbitrary (AccumulateRight a b)’
   |
22 | instance Arbitrary (Validation a b) => Arbitrary (AccumulateRight a b) where
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.

我在这做错了吗?为什么我不能使用现有数据的类型类作为约束?

haskell polymorphism typeclass parametric-polymorphism
1个回答
4
投票

在了解类型类的实现难度之前,这是一个愚蠢的限制。事实证明它很容易支持,所以有一个语言扩展 - 在错误中提到 - 可以让你这么说。你可以通过添加打开它

{-# LANGUAGE FlexibleContexts #-}

在文件的顶部,作为扩展,这个被认为是完全良性的。但是,在这种情况下,您不应该打开它,而应该只写

instance (Arbitrary a, Arbitrary b) => Arbitrary (AccumulateRight a b)

- 毕竟,(Arbitrary a, Arbitrary b)正是Arbitrary (Validation a b)所持有的条件。

© www.soinside.com 2019 - 2024. All rights reserved.