Играя с TypeOperators
Я пробовал реализовать $
и .
, поэтому я могу избавить свою программу от любых круглых скобок (не обижайтесь ни на какие красивые Лисперсы там). При этом я изоморфно скопировал определения. Сначала я попытался использовать только $
, потому что вам не нужно .
с его мощной силой.Последовательность типов-операторов и требования к типу
{-# LANGUAGE TypeOperators #-}
type f $ a = f a
f :: Int -> IO $ Either String Int
f n = undefined
Отлично. Это компилируется, и я доволен.
{-# LANGUAGE TypeOperators #-}
type f $ a = f a
f :: Int -> IO $ Maybe $ Either String Int
f n = undefined
Это должно работать правильно?
TyCo.hs:4:18:
Expecting one more argument to ‘Maybe’
The second argument of ‘$’ should have kind ‘*’,
but ‘Maybe’ has kind ‘* -> *’
In the type signature for ‘f’:
f :: Int -> (IO $ Maybe) $ Either String Int
Видимо нет.
{-# LANGUAGE TypeOperators #-}
type f $ a = f a
type (f * g) a = f (g a)
f :: Int -> IO * Maybe $ Either String Int
f n = undefined
С слепой надеждой, я стараюсь.
TyCo.hs:5:6:
Type synonym ‘*’ should have 3 arguments, but has been given 2
In the type signature for ‘f’:
f :: Int -> (IO * Maybe) $ Either String In
В моем невежественном ступоре я поднимаю вопрос: WHY
она не работает?
Для вашего первого примера это похоже на то, что ассоциативность '$' неверна. Я полагаю, что '$' на уровне значений и '$' на уровне типа считаются разными идентификаторами, и мы не объявили о приоритете или ассоциативности для последнего. Я не знаю, как это сделать, или если есть способ. По крайней мере, играйте с 'infixr' немного ... – luqui
Вы также должны включить' PolyKinds' и/или 'LiberalTypeSynonyms', если вы ожидаете, что эти ярлыки будут в целом полезными. – luqui
@ Комментарии luqui находятся на правильном пути. Вы можете исправить первую версию с 'infixr 0 $', а вторую версию - с помощью 'LiberalTypeSynonyms'. –