Унифицирующий тип записи

В качестве обучающего упражнения я пытаюсь определить новый тип, который будет служить держателем функций, которые могут преобразовывать Show-способные значения в Effects, то есть:

newtype ShEff a = ShEff (forall eff. Show a => a -> Eff eff Unit)

Однако это:

f :: forall a. ShEff a
f = ShEff logShow

не удается скомпилировать с этой ошибкой:

  Could not match type

    ( console :: CONSOLE
    | t2
    )

  with type

    eff1


while trying to match type Eff
                             ( console :: CONSOLE
                             | t2
                             )
  with type Eff eff1
while checking that expression logShow
  has type t0 -> Eff eff1 Unit
in value declaration f

Можете ли вы указать мне правильное направление?


person levant pied    schedule 06.04.2017    source источник


Ответы (1)


Тип logShow -

forall eff. Show a => a -> Eff (console :: CONSOLE | eff) Unit

поэтому вы не можете хранить его внутри ShEff, поскольку это должно работать для каждого eff, а logShow работает только для строк, содержащих эффект CONSOLE.

У вас есть два варианта:

  1. Переместите аргумент типа eff за пределы ShEff:

    newtype ShEff eff a = ShEff (a -> Eff eff Unit)
    
    f :: forall a eff. Show a => ShEff (console :: CONSOLE | eff) a
    f = ShEff logShow
    
  2. Добавьте ограничение внутри ShEff:

    newtype ShEff a = ShEff (forall eff. a -> Eff (console :: CONSOLE | eff) Unit)
    
    f :: forall a eff. Show a => ShEff a
    f = ShEff logShow
    

Также обратите внимание, что в обоих случаях я переместил ограничение Show a за пределы ShEff.

person Phil Freeman    schedule 07.04.2017