Отслеживается для данных Constant a b = Constant a проходит Quickchecks, но действует смешно

Книга Haskell хочет, чтобы я реализовал проходимый экземпляр для

newtype Constant a b = Constant { getConstant :: a }

включая все необходимые суперклассы. Код ниже проходит Quickcheck/Checkers, но действует смешно

import Test.QuickCheck
import Test.QuickCheck.Checkers
import Test.QuickCheck.Classes

newtype Constant a b = Constant { getConstant :: a }

instance Functor (Constant a) where
  fmap f (Constant a) = Constant a

instance Foldable (Constant a) where
  foldr f z (Constant x) = z

instance Traversable (Constant a) where
  traverse f (Constant a) = pure $ Constant a    

type TI = []
main = do
  let trigger = undefined :: TI (Int, Int, [Int])
  quickBatch (traversable trigger)

Когда я пытаюсь использовать проходимый экземпляр, вот так:

traverse (\x -> [x + 1]) $ Constant 5 

Я не понимаю Constant [5] на что я надеялся, но скорее

traverse (\x -> [x + 1]) $ Constant 5
  :: (Num b, Num a) => [Constant a b]

Что это значит? Я сделал что-то не так?

1 ответ

Решение

Когда я пытаюсь использовать проходимый экземпляр, вот так:

traverse (\x -> [x + 1]) $ Constant 5 

Я не понимаю Constant [5] на который я надеялся [...]

Вы не собираетесь получить Constant [5], Давайте напишем тип для traverse:

traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)

... и выровняйте это с вашей реализацией этого:

                  -- I've substituted `x` for `a` and `y` for `b` in the
                  -- first type, because otherwise my head hurts.
                  (x -> f  y) -> t            x -> f  (t            y)
(Num a, Num b) => (a -> [] a) -> (Constant b) a -> [] ((Constant b) a)

Итак, мы имеем:

t = Constant b
f = []
x = Num a => a
y = NUm b => b

Обратите внимание, что тип для traverse подразумевает, что t будет одинаковым в аргументе и результате. Так как вы используете Constant 5 :: Num a => Constant a b в качестве аргумента, это означает, что вы никогда не можете иметь Constant [5] :: Num a => Constant [a] b в результате, потому что Constant a /= Constant [a],

Другие вопросы по тегам