Пусть следующие типы данных определяются:Функции с более высокими видами?
data X a = X {getX :: a}
data Y a = Y {getY :: a}
data Z a = Z {getZ :: a}
Должен ли быть три отдельных функций, getX
, getY
и getZ
? Мне кажется, что там может быть функция, определенная что-то вроде этого:
get :: forall (τ :: (* -> *)) (a :: *). τ a -> a
get (_ x) = x
Очевидно, что это не является допустимым стандартом Haskell, но есть очень много расширений к GHC, которые, кажется, что они могли бы иметь решение (RankNTypes
, ExistentialQuantification
, DataKinds
и т. Д.). Помимо простой причины избежать крошечного набора текста, есть преимущество избежать загрязнения пространства имен, создаваемого решением записи. Я предполагаю, что это на самом деле просто более неявное решение, чем класс типа, как это:
class Get f where
get :: f a -> a
Однако представляется, что определение обобщенной функции было бы более полезным, чем класс типа, так как тот факт, что она неявно что он может использоваться во многих других местах, так же, как используется ($)
или (.)
. Поэтому мой вопрос состоит из трех частей: есть ли способ сделать это, это хорошая идея, а если нет, то что лучше?
Что бы ваша функция 'get' выполняла, если ему был предоставлен список (т. Е. Если' τ' был '[]')? – duplode
Ну, это делает неявное предположение, что это не сработает.Нет причин предполагать тип с конечной переменной типа вида * имеет один конструктор, который принимает один аргумент рассматриваемого типа. – Carl