Группирующие функции в Haskell

Используя Haskell, я хотел бы сгруппировать функции вместе, как если бы я использовал объектную ориентацию в других языках. Конкретно следуя ответу на этот вопрос

Поддерживает ли Haskell объектно-ориентированное программирование

допустим, у меня есть тип

data Class = Obj { a :: Int -> Int, b :: Int -> Int }

а теперь я хочу определить несколько других функций (как бы методов), производных от a и b. Один из способов сделать это - определить что-то вроде

c :: Class -> Int -> Int
c obj x = myb (mya x)
    where mya = a obj
          myb = b obj

d :: Class -> Int -> Int
d obj x = myb (myc x)
    where myb = b obj
          myc = c obj

Однако это означает, что в каждом шаблоне регулярное выражение мне нужно явно указать (в предложении where), какие другие функции я использую. У меня вопрос: есть ли более короткий способ добиться этого?

каждое "регулярное выражение"?

Willem Van Onsem 18.04.2018 10:33

Естественный способ «сгруппировать» функции и их данные в Haskell - это модули.

MathematicalOrchid 18.04.2018 10:33

Какая именно цель? Какое-то наследство? Возможно, вас заинтересует Почему я должен предпочесть композицию наследованию?? Возможно, вы могли бы указать пример использования этого шаблона. Выполнение в Haskell вещей, подобных ООП, может иметь несколько целей; Вы проводите собственное исследование шаблонов программирования или пытаетесь повторно использовать шаблоны, уже имеющиеся у вас за поясом, вместо того, чтобы изучать новые?

Simon Shine 18.04.2018 10:34

Хотя программирование объектно-ориентированныйможет может быть достигнуто в Haskell (в том смысле, что вы можете сделать что-то довольно похожее), обычно не стоит менять парадигму.

Willem Van Onsem 18.04.2018 10:36

Пример использования такой: в зависимости от набора параметров у меня есть две основные функции перезаписи слов. Используя их, я могу определить производные функции перезаписи и в конечном итоге получить функцию, вычисляющую нормальную форму. Теперь предполагается, что тип представляет два основных правила перезаписи (или, что эквивалентно, параметры), а затем все производные правила принадлежат одним и тем же параметрам.

Stefan Witzel 18.04.2018 11:19

Возможно, мне не стоило упоминать об объектной ориентации, потому что теперь все сигналы тревоги срабатывают еще до того, как кто-либо прочитает то, что я на самом деле спрашиваю.

Stefan Witzel 18.04.2018 11:24

Вот тот же вопрос без упоминания об ориентации объекта: stackoverflow.com/questions/49897341/…

Stefan Witzel 18.04.2018 12:28
В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Принцип подстановки Лискова
Принцип подстановки Лискова
Принцип подстановки Лискова (LSP) - это принцип объектно-ориентированного программирования, который гласит, что объекты суперкласса должны иметь...
0
7
255
1

Ответы 1

Если ваша цель - просто не печатать слишком много, вы можете использовать расширение RecordWildCards:

{-# LANGUAGE RecordWildCards #-}

data Class = Obj { a :: Int -> Int, b :: Int -> Int }

f :: Class -> Int -> Int
f Obj{..} x = a x + b x

Тогда вы можете использовать это так: f (Obj id id) 10 == 20

Обратите внимание, что это затеняет фактические «средства доступа к полям», поэтому это не сработает, если вы по-прежнему хотите использовать их в той же функции по какой-то причине.

Без расширений всегда можно просто написать

f (Obj a b) x = a x + b x

(Типы записей могут быть сопоставлены с шаблоном с использованием обычного синтаксиса конструктора).

Спасибо! Это решает вопрос, но только для функций a и b. Могу ли я также избавиться от "where myb = b obj"?

Stefan Witzel 18.04.2018 12:27

@StefanWitzel Я не понимаю, о чем ты? myb = b obj здесь не нужен.

Cubic 18.04.2018 12:33

При определении функции d выше я использовал функцию c. Ваше решение не записывать mya и myb зависит от того факта, что это поля класса, поэтому избежать записи myc не получится.

Stefan Witzel 18.04.2018 13:39

Другие вопросы по теме