Возможно, вы сможете сделать это в GHC 8.0, используя новый TypeError, в зависимости от того, что вы подразумеваете под "заставить второй аргумент быть парой".
{-# LANGUAGE TypeFamilies, DataKinds, TypeOperators, UndecidableInstances #-}
module Pair where
import GHC.TypeLits
type family Fst p where
Fst (x, y) = x
Fst _t = TypeError (Text "Fst: expected a pair, but got " :<>: ShowType _t)
type family Snd p where
Snd (x, y) = y
Snd _t = TypeError (Text "Snd: expected a pair, but got " :<>: ShowType _t)
type family TF a b
type instance TF Int t = (Int, Fst t, Snd t)
Теперь вы должны получить ошибку компиляции, если попытаетесь применить TF Int
к не-кортежу:
*Pair> let x = x in x :: TF Int Bool
<interactive>:9:1: error:
• Fst: expected a pair, but got Bool
• When checking the inferred type
it :: (Int, (TypeError ...), (TypeError ...))
Однако на самом деле это не «заставляет» аргумент быть парой больше, чем вызов fromJust
«принуждает» его аргумент иметь форму Just x
. Это действительно программирование с частичными функциями на уровне типа.
Корректность приложений семейства типов полностью определяется видом семейства типов, и пара (x, y)
имеет тот же тип *
, что и, скажем, Bool
. Вы не можете волшебным образом навлечь на себя ограничение, просто написав приложение семейства типов. Если вы хотите получить ограничение на уровне типа, вы должны написать его слева от =>
.
В связанном вопросе CanFilter (b -> c) a
уже является ограничением, поэтому оно может подразумевать b ~ c
.
person
Reid Barton
schedule
15.02.2016
x,y
не входит в область действия. Как написано, это по существу будет включать экзистенциальные типы, которые не являются первоклассными в Haskell. - person chi   schedule 15.02.2016type family Fst x where Fst (x,y) = x; type family Snd x where Snd (x,y) = y; type instance TF Int t = (Int, Fst t, Snd t)
. Проще всего дать вашему индексу одно закрытое семейство, которое сокращается только для пар:type instance TF Int x = TF_Int x; type family TF_Int x where TF_Int (x,y) = (Int, x, y)
. - person user2407038   schedule 15.02.2016Fst
/Snd
более ленивый и, следовательно, позволит более полезные сокращения. - person dfeuer   schedule 16.02.2016