Классы типов SRTP в F # - PullRequest
1 голос
/ 17 марта 2019

Я был очень впечатлен библиотекой FSharpPlus и тем, как она позволяет эмулировать некоторые общие классы типов.Но я действительно верю в силу отделения экземпляра класса типов от определения типа, поэтому я пытался создать концептуальное подтверждение использования некоторых из тех же методов, что и FSharpPlus, но рассматривая экземпляр класса типов как совершенно отдельныйюридическое лицо.Честно говоря, я немного расширяю свои возможности SRTP, и источник FSharpPlus находится немного над моей головой.Вот моя попытка на данный момент:

module Monad =
  let inline bind (m:^Monad) (f:'a -> '``Monad<'b>``) (x:'``Monad<'a>``) : '``Monad<'b>`` = 
    (^Monad : (member Bind : _*_ -> _) (m, f, x))

  let inline rtn (m:^Monad) (source:'a) : '``Monad<'a>`` = 
    (^Monad : (member Return : _ -> _) (m, source))

type ListMonad = ListMonad with 
  member this.Bind (f, x) = List.collect f x
  member this.Return x = [x]

type OptionMonad = OptionMonad with 
  member this.Bind (f, x) = Option.bind f x
  member this.Return x = Some x

Это позволяет мне делать некоторые базовые вещи, но я врезаюсь в стену, как только пытаюсь использовать bind дважды в одной функции:

let inline applyFromMonad (monadInstance) (f:'``Monad<'a -> 'b>) (x:'``Monad<'a>``) : '``Monad<'b>`` = 
  f |> Monad.bind monadInstance (fun f' ->
  x |> Monad.bind monadInstance (fun a' ->
  Monad.rtn monadInstance (f' a')))

(я буду беспокоиться о реализации выражений вычислений позже).Проблема в том, что компилятор ожидает, что f' и a' будут того же типа , предположительно потому, что Monad.bind не рассматривается как достаточно универсальный.Вместо параметра f функции связывания, обрабатываемой как функция, принимающая любой универсальный тип 'a, он обрабатывается как функция, принимающая некоторый конкретный тип в функции applyFromMonad.Есть ли способ обойти это так, чтобы bind можно было задавать аргументы разных типов при двойном вызове?

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...