Держите объектив в записи - PullRequest
0 голосов
/ 25 января 2019

У меня есть запись MyRecord, для которой я создаю линзы с makeLenses.Я хотел бы, чтобы в этой записи было поле, которое само по себе является объективом, но также доступно с объективом, как и другие поля.

Вот мой код для достижения этой цели:

{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE RankNTypes #-}

module Check where

import Lens.Micro ( Lens' )
import Lens.Micro.TH ( makeLenses )

data MyRecord a = 
  MyRecord { _normalField :: Int
           , _myField :: Lens' (String, String) a 
           }

makeLenses ''MyRecord

Код компилируется нормально, если я пишу myField вместо _myField, но таким образом для него не будет сгенерировано объектива.

Для данного кода ghc выводит

/home/fabian/src/code-editor/app/Check.hs:11:1: error:
    • Illegal polymorphic type: Lens' (String, String) a2
      GHC doesn't yet support impredicative polymorphism
    • In the type signature:
        myField :: forall a_a5c6 a_a8tU.
                   Lens.Micro.Type.Lens (MyRecord a_a5c6) (MyRecord a_a8tU) (Lens' (String,
                                                                                    String) a_a5c6) (Lens' (String,
                                                                                                            String) a_a8tU)
   |
11 | makeLenses ''MyRecord

Может кто-нибудь кратко объяснить, что здесь происходит, и есть ли хорошее решение для этого?

1 Ответ

0 голосов
/ 25 января 2019

Я считаю, что обычным решением являются типы ранга 1, такие как ALens .Я не знаю, предоставляет ли семейство microlens нечто подобное.

Руководство GHC объясняет проблему и решение.Он начинается:

Как правило, GHC создает экземпляр полиморфной функции только в мономорфном типе (тот, у которого нет повторений).[...] Определение foo отклонено, потому что нужно создать экземпляр типа id с помощью b := (forall s. ST s a) -> a, а это недопустимо.Выявление переменных полиморфного типа с полиморфными типами называется непредсказуемым полиморфизмом.

...