Решение ограничения класса, который зависит от ограничения - PullRequest
2 голосов
/ 29 июня 2019

Я использую ConstraintKinds и MultiParamTypeClasses, чтобы получить класс, параметризованный другим классом.

Предположим, Foo m говорит, что типы, которые удовлетворяют ограничению m, являются указанными, то есть(m a) => a.Исходя из этого, я пытаюсь использовать его для построения некоторого Bar m.

{-# LANGUAGE AllowAmbiguousTypes   #-}
{-# LANGUAGE ConstraintKinds       #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE GADTs                 #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes            #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE TypeOperators         #-}

class Foo m where
  foo :: (m a) => a

data Bar m where
  Bar :: ((m a) => a) -> Bar m

bar :: Foo m => Bar m
bar = Bar foo

Но я получаю следующую ошибку.

Could not deduce (Foo m0) arising from a use of ‘foo’
      from the context: Foo m

Из контекста выглядит так: m0 должно быть m.Разве нет способа заставить это работать?


Я думаю, что сейчас проблема в том, что я мог бы сначала определить некоторые Foo Pointed a, а затем некоторые Foo Pointed2 a, и в этом случае foo не будет знать, что возвращать, верно?Идея в том, что я бы позвонил (bar :: Bar Pointed) или (bar :: Bar Pointed2) и получил бы два разных результата.Возможно ли что-то подобное?Почему нет?

1 Ответ

2 голосов
/ 29 июня 2019

Похоже, что вы можете сделать это с помощью приложения типа, чтобы помочь GHC выяснить, о каком ограничении вы говорите:

bar :: forall m . (Foo m) => Bar m
bar = Bar (foo @m)
...