Предположим, что у меня есть эти определения данных в Haskell.Как написать общую функцию для любого конструктора данных?
data Point a = Point a a
data Piece a = One a | Two a
и я хочу иметь одну функцию, как
place :: Num a => Piece (Point a) -> Point a
place (Piece x) = x
, как я могу это сделать, так как Haskell не позволяет функции этой конкретной формы.
Решение
Проблема заключалась в мое определение данных (много лет эмпирического программирования мешая здесь ...). Я хотел, чтобы мои данные Piece эффективно представляли собой две разные вещи: кусок, а также какую-то часть, я пытался добиться этого с наследованием, которое было всего лишь плохим подходом. Разделение данных следующим образом разрешило проблему.
data PieceKind = One | Two | ... | n
data Piece a b = Piece a PieceKind
Таким образом, моя пьеса действительно имеет два атрибута «а» (в моем случае это позиция части), а также PieceKind, таким образом, я был в состоянии написать функцию места без необходимости повторять его каждый вид части следующим образом:
place :: Num a => Piece (Point a) PieceKind -> Point a
place (Piece x _) = x
Кроме того, я также был в состоянии писать функции для определенного вида кусок:
place :: Num a => Piece (Point a) PieceKind -> Point a
place (Piece _ One) = ...
и это то, что я действительно хотел.
Является ли ваше намерение заставить его работать как 'place (One x) = x; место (два x) = x'? –
Да, вместо одной функции для каждого конструктора я хочу иметь только одну функцию для всех из них. –
Задайте свой вопрос самостоятельно, указав «Точка». – Jubobs