Не удалось разрешить экземпляр типа Haskell - PullRequest
0 голосов
/ 02 июля 2018

Я пытаюсь создать Cofree структуру по анаморфизму, согласно этой записи . Но компилятор жалуется на несоответствие типов:

Expected type: Base (Cofree Term E) (E, Fix Term)
  Actual type: CofreeF Term E (E, Fix Term)

Но в исходном коде пакета recursion-schemes есть определение экземпляра типа:

type instance Base (Cofree f a) = CofreeF f a

Как я могу заставить компилятор haskell унифицировать этот тип с этим конкретным уравнением экземпляра типа?

Код практически такой же, как в ссылке:

import qualified Control.Comonad.Trans.Cofree as COFREEF

type E = Int
type Term = Maybe

annotate :: E -> Fix Term -> COFREEF.Cofree Term E
annotate = curry (ana coalg)
  where
    coalg :: (E, Fix Term) -> COFREEF.CofreeF Term E (E, Fix Term)
    coalg (environment, Fix term) = environment COFREEF.:< fmap ((,) 
environment) term

И точное сообщение об ошибке:

Couldn't match type ‘COFREEF.CofreeF Term E (E, Fix Term)’
                 with ‘Compose
                         Data.Functor.Identity.Identity
                         (COFREEF.CofreeF Maybe Int)
                         (E, Fix Term)’
  Expected type: (E, Fix Term)
                 -> Base (COFREEF.Cofree Term E) (E, Fix Term)
    Actual type: (E, Fix Term)
                 -> COFREEF.CofreeF Term E (E, Fix Term)
• In the first argument of ‘ana’, namely ‘coalg’
  In the first argument of ‘curry’, namely ‘(ana coalg)’
  In the expression: curry (ana coalg)

1 Ответ

0 голосов
/ 03 июля 2018

Cofree это просто синоним типа

newtype CofreeT f w a = CofreeT { runCofreeT :: w (CofreeF f a (CofreeT f w a)) }
type Cofree f = CofreeT f Identity

и CofreeT имеет экземпляр Base:

type instance Base (CofreeT f w a) = Compose w (CofreeF f a)
-- Base (Cofree f a) ~ Base (CofreeT f Identity a) ~ Compose Identity (CofreeF f a)

Уравнение из вопроса морально эквивалентно, но не является достаточно хорошим приближением.

Оберните свою коалгебру в Compose . Identity

annotate :: E -> Fix Term -> Cofree Term E
annotate = curry $ ana $ Compose . Identity . coalg
  where
    coalg :: (E, Fix Term) -> CofreeF Term E (E, Fix Term)
    coalg (environment, Fix term) = environment :< fmap (environment,) term
...