История изменений
Исправление quasimoto, (текущая версия) :
У тебя Any Int и Any Real вместо Int и Real
У меня Any _Real_ и Any _ShowFractional_, где Real и ShowFractional - классы. И сделано это исключительно чтобы инкапсулировать квантифицируемую переменную, как ты просил. Вместо GADTs + ConstraintKinds можно сделать просто с ExistentialQuantification:
data RealT = forall a. Real a => RealT a
data ShowFractionalT = forall a. (Show a, Fractional a) => ShowFractionalT
но это менее удобно.
Теперь не переписывая эту функцию и ее тип определи какой-нибудь подтип RealT который можно будет передать в +.
В (+.) уже можно передавать всё что угодно, достаточно написать этому инстанс Real и обернуть в Any.
Там нет объединений, просто типы параметризированные числами, например, Vec : Nat -> Set -> Set и потом Vec 5 Int, то есть совсем не то что было в примерах с Racket. 5 как был термом, так и есть, тут ни он ни нечто вспомогательное не используется как тип. С пакетом type-level так можно делать, только вместо 5 будет D5, где D5 :: * и не имеет нормальных термов.
http://hackage.haskell.org/trac/ghc/wiki/DeferErrorsToRuntime
А это про расставление (достаточно полиморфного) error на месте плохого кода вместо генерации ошибок во время компиляции.
Исходная версия quasimoto, :
У тебя Any Int и Any Real вместо Int и Real
У меня Any _Real_ и Any _ShowFractional_, где Real и ShowFractional - классы. И сделано это исключительно чтобы инкапсулировать квантифицируемую переменную, как ты просил. Вместо GADTs + ConstraintKinds можно сделать просто с ExistentialQuantification:
data RealT = forall a. Real a => RealT a
data ShowFractionalT = forall a. (Show a, Fractional a) => ShowFractionalT
но это менее удобно.
Теперь не переписывая эту функцию и ее тип определи какой-нибудь подтип RealT который можно будет передать в +.
В (+.) уже можно передавать всё что угодно, достаточно написать этому инстанс Real и обернуть в Any.
Там нет объединений, просто типы параметризированные числами, например, Vec : Nat -> Set -> Set и потом Vec 5 Int, то есть совсем не то что было в примерах с Racket. 5 как был термом, так и есть, тут ни он ни нечто вспомогательное не используется как тип. С пакетом type-level так можно делать, только вместо 5 будет D5, где D5 :: * и не имеет нормальных термов.
http://hackage.haskell.org/trac/ghc/wiki/DeferErrorsToRuntime
А это про расставление error на месте плохого кода вместо генерации ошибок во время компиляции.