簡體   English   中英

任意類型類的約束中的非類型變量參數

[英]Non type-variable argument in the constraint for Arbitrary typeclass

對於在Haskell編程從第一原理的第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.

那我在這做錯了嗎? 為什么在這里我不能使用現有數據的類型類作為約束?

這是一個愚蠢的限制,在人們理解類型類很難實現之前就已經施加了限制。 事實證明,它很容易支持,因此有一個語言擴展(錯誤中提到),您可以這樣說。 您可以通過添加將其打開

{-# LANGUAGE FlexibleContexts #-}

到文件的頂部,隨着擴展名的增加,這是完全良性的。 但是,在這種情況下,您不應該打開它,而應該只寫

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

-畢竟(Arbitrary a, Arbitrary b)正是Arbitrary (Validation ab)成立的條件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM