Редактировать: Вот действительно простой пример. Мотивация для этого примера ниже.Добавление логической сигнатуры типа ghci вызывает ошибку
компилируется:
{-# LANGUAGE TypeFamilies #-}
type family F a b
f :: a -> F a b
f = undefined
f' [a] = f a
И GHCi сообщает, что:
*Main> :t f'
f' :: [a] -> F a b
Но если мы добавим этот тип подписи файла выше, он жалуется:
*Main> :r
[1 of 1] Compiling Main (test.hs, interpreted)
test.hs:9:14:
Couldn't match type `F a b0' with `F a b'
NB: `F' is a type function, and may not be injective
In the return type of a call of `f'
In the expression: f a
In an equation for `f'': f' [a] = f a
Failed, modules loaded: none.
Что дает ?
Мотивация:
Осмотрев this question, я думал, что быть умной, сельдью и написать небольшое решение шутки. План атаки должен начинаться с номеров типа (как обычно), а затем писать небольшую функцию уровня Args n a c
, которая дает тип функции, который принимает n
копий a
и дает c
. Затем мы можем написать небольшой класс типа для различных n
и быть на нашем пути. Вот что я хочу написать:
{-# LANGUAGE TypeFamilies #-}
data Z = Z
data S a = S a
type family Args n a c
type instance Args Z a c = c
type instance Args (S n) a c = a -> Args n a c
class OnAll n where
onAll :: n -> (b -> a) -> Args n a c -> Args n b c
instance OnAll Z where
onAll Z f c = c
instance OnAll n => OnAll (S n) where
onAll (S n) f g b = onAll n f (g (f b))
я с удивлением обнаружил, что это не тип проверки!
Это, безусловно, больше усилий, чем я посвятил упрощению этого примера! Какую версию GHC вы используете, прежде чем я попытаюсь углубиться в это? – ehird
@ehird Я проверил с ghc-7.2.2 и ghc-7.3.20111114. –
(Мое подозрение, FWIW, заключается в том, что это ошибка в GHC. Тем не менее, я думаю, что 'NB:' Args 'является функцией типа и может быть неинъекционной'' также может быть релевантной, ошибка может быть просто как ': t' отображает имена и т. п., а не в самом типе-контролере.) – ehird