Haskell ZipList Applicative - PullRequest
       13

Haskell ZipList Applicative

0 голосов
/ 17 мая 2018

Я пытаюсь написать экземпляр Applicative для моего ZipList и получаю некоторые запутанные результаты.

data List a =
    Nil
  | Cons a (List a)
  deriving (Eq, Show)

newtype ZipList' a =
  ZipList' (List a)
  deriving (Eq, Show)

instance Applicative ZipList' where
  pure = ZipList' . flip Cons Nil
  (<*>) (ZipList' Nil) _ = ZipList' Nil
  (<*>) _ (ZipList' Nil) = ZipList' Nil
  (<*>) (ZipList' (Cons f fs)) (ZipList' (Cons x xs)) =
    ZipList' $ Cons (f x) (fs <*> xs)

Он работает, как и ожидалось, для ZipLists длиной 1 или 2:

> ZipList' (Cons (*2) (Cons (+9) Nil)) <*> ZipList' (Cons 5 (Cons 9 Nil))
ZipList' (Cons 10 (Cons 18 Nil))

Но когда я перехожу к 3+, я получаю странные результаты:

> ZipList' (Cons (*2) (Cons (+99) (Cons (+4) Nil))) <*> ZipList' (Cons 5 (Cons 9 (Cons 1 Nil)))
ZipList' (Cons 10 (Cons 108 (Cons 100 (Cons 13 (Cons 5 Nil)))))

Результатом должен быть ZipList из 10, 108, 5 - но каким-то образом 100 и 13 приводят к сбоюparty.

Итак, я попытался извлечь свою функцию из экземпляра, чтобы я мог проверить тип, который выводит Haskell:

(<**>) (ZipList' Nil) _ = ZipList' Nil
(<**>) _ (ZipList' Nil) = ZipList' Nil
(<**>) (ZipList' (Cons f fs)) (ZipList' (Cons x xs)) =
  ZipList' $ Cons (f x) (fs <**> xs)

, но он не скомпилируется!

17-applicative/list.hs:94:26: error:
    • Couldn't match expected type ‘ZipList' (a0 -> b0)’
                  with actual type ‘List (a -> b)’
    • In the first argument of ‘(<**>)’, namely ‘fs’
      In the second argument of ‘Cons’, namely ‘(fs <**> xs)’
      In the second argument of ‘($)’, namely ‘Cons (f x) (fs <**> xs)’
    • Relevant bindings include
        xs :: List a (bound at 17-applicative/list.hs:93:49)
        x :: a (bound at 17-applicative/list.hs:93:47)
        fs :: List (a -> b) (bound at 17-applicative/list.hs:93:26)
        f :: a -> b (bound at 17-applicative/list.hs:93:24)
        (<**>) :: ZipList' (a -> b) -> ZipList' a -> ZipList' b
          (bound at 17-applicative/list.hs:91:1)

Ошибка говорит мне, что я пытаюсь передать список, где ожидается ZipList, который я вижу.Но как же тогда мой экземпляр Applicative скомпилировался?

1 Ответ

0 голосов
/ 17 мая 2018

Проблема в <*> в ZipList' $ Cons (f x) (fs <*> xs).

Это не ZipList' <*>, это List.

Попробуйте ZipList' $ Cons (f x) (case ZipList' fs <*> ZipList' xs of ZipList ys -> ys) `

...