Я пытаюсь перевести стрелы активной библиотеки Haskell в F # (я думаю, что это хорошее упражнение для понимания стрелок и F # лучше, и я мог бы использовать их в проекте, над которым я работаю.) Однако, прямой перевод невозможен из-за различий в парадигмах. Haskell использует типы классов для выражения этого материала, но я не уверен, что конструкция F # наилучшим образом отображает функциональность классов типов с идиомами F #. У меня есть несколько мыслей, но я решил, что лучше всего поднять его здесь и посмотреть, что считается самым близким по функциональности.Как перевести класс типа Haskell в F #?
Для толпы tl; dr: Как перевести типы классов (икону Haskell) в Идиоматический код F #?
Для тех, принимая моего долгого объяснения:
Этот код из стандартного Lib Haskell является примером того, что я пытаюсь перевести:
class Category cat where
id :: cat a a
comp :: cat a b -> cat b c -> cat a c
class Category a => Arrow a where
arr :: (b -> c) -> a b c
first :: a b c -> a (b,d) (c,d)
instance Category (->) where
id f = f
instance Arrow (->) where
arr f = f
first f = f *** id
Попытка 1: Модули, Простые типы , Пусть Наручники
Мой первый выстрел в это просто карта вещи более непосредственно с помощью модулей для организации, как:
Это работает, но оно теряет полиморфизм, поскольку я не реализую Категории и не могу легко реализовать более специализированные стрелки.
Покушения 1a: нефтепереработка использование Подписи и типов
Один из способов исправить некоторые проблемы с Покушением 1 является использование .fsi файла, чтобы определить методы (так типов соблюдения проще) и использовать некоторые простые типа для специализации.
type ListArrow<'a,'b> = Arrow<['a],['b]>
//or
type ListArrow<'a,'b> = LA of Arrow<['a],['b]>
Но файл FSI не может быть повторно использован (для обеспечения типов Выпускаемого связанными функций) для других реализаций, а также типа переименовывать/герметизирующий материал сложен.
Попытка 2: Объектные модели и интерфейсы
Рационализация, что F # построен быть OO также, возможно, иерархия типов является правильный способ сделать это.
type IArrow<'a,'b> =
abstract member comp : IArrow<'b,'c> -> IArrow<'a,'c>
type Arrow<'a,'b>(func:'a->'b) =
interface IArrow<'a,'b> with
member this.comp = //fun code involving "Arrow (fun x-> workOn x) :> IArrow"
Кроме того, сколько боли это может быть, чтобы получить то, что должно быть статическими методами (например, комп и другими операторы), чтобы действовать как методы экземпляра, есть также необходимость явно базовый типа результатов. Я также не уверен, что эта методология все еще захватывает полную выразительность полиморфизма типового класса. Это также затрудняет использование вещей, которые ДОЛЖНЫ быть статическими методами.
Покушение 2a: нефтепереработка с использованием расширений типа
Так что еще один потенциальное уточнением объявить интерфейсы, как босые, насколько это возможно, а затем использовать методы расширения для добавления функциональности для всех типов исполнителей.
type IArrow<'a,'b> with
static member (&&&) f = //code to do the fanout operation
Ах, но это заставляет меня использовать один метод для всех типов IArrow.Если бы я хотел немного отличаться (& & &) для ListArrows, что мне делать? Я еще не пробовал этот метод, но я бы предположил, что могу тень (& & &), или, по крайней мере, предоставить более специализированную версию, но я чувствую, что не могу обеспечить использование правильного варианта.
Помоги мне
Так что я должен здесь делать? Я чувствую, что OO должно быть достаточно мощным, чтобы заменить классы типа, но я не могу понять, как это произошло в F #. Были ли какие-либо из моих попыток закрыты? Кто-нибудь из них «так хорош, как он», и это должно быть достаточно хорошо?
«Как перевести типы классов (икону Haskell) в Идиоматический код F #?» Плохая идея. Вы должны посмотреть на * проблему *, которую вы пытались решить, вместо решения, которое использовало классы типов, и выяснить, как его решить, используя функцию, которую предоставляет F #. –
@Jon Harrop В этом суть вопроса. Haskell решает десятки проблем с классами типа, и я хотел знать, какие альтернативы F # решали аналогичный * класс * проблем.Также порт Arrow не должен решать никаких проблем, его просто «я думал, что было бы интересно узнать больше о стрелках». – CodexArcanum
Тогда я думаю, что было бы очень полезно, если бы вы могли объяснить некоторые проблемы, которые решали типы классов, и спросить людей, как они решат те же проблемы в F #. –