Если ответ на этот вопрос: «вы все это делаете неправильно», непременно сообщите мне более подходящий способ. У меня был код, который был структурирован так:Попытка получить связывание, работающее для сочетания государственной и отложенной монады
type Res<'T> =
| E of (DC -> 'T)
| V of 'T
Теперь этот тип в основном используется непосредственно, с большим количеством встроенного кода, который сделал руководство по случаю связывания, который много шаблонного Я пытаюсь избавиться из, поэтому я решил, что превращаю его в выражение вычисления. Было не так сложно получить map, bind и применить право.
Состояние было перенесено через округ Колумбия, но это было громоздким, чтобы получить право, поэтому я изменил его на следующее, что является общей подписью, которую я вижу в обсуждениях с государственной монадой.
type Res<'T> =
| E of (DC -> DC * 'T)
| V of 'T
Тогда я решил взять его на следующий уровень и ввести Delayed монады (или В конце концов, или независимо от его имени). Таким образом, я изменил свой тип следующим образом, что делает его рекурсивным:
type Res<'T> =
| E of (DC -> DC * Res<'T>)
| V of 'T
Я попробовал несколько вариантов ниже, но постоянно получаю:
Результирующий тип будет бесконечным, когда объединяющим «» а»и 'Res <' а> -> Res < 'б>'
(обычно случается, когда я не призываю возвращения, то есть ниже Res.E <|
)
Или я не могу показаться, чтобы получить свои типы права, следующие (по понятным причинам) вызывает ошибку типа, но у меня слепое пятно фиксируя его:
Это выражение, как ожидается, иметь тип 'Res <' a> ', но здесь есть тип' DC * Res < 'a>'.
let rec bind k res =
match res with
| Res.V v -> k v // not delayed, should it be?
| Res.E e ->
Res.E <| fun dc -> bind k (e dc) // here's my error, on 'e dc'
//(fun dc -> dc, bind f (e dc))
bind k res
Я понимаю, что подпись должна быть ('a -> Res<'b>) -> Res<'a> -> XRes<'b>
. Проблема заключается в том, что рекурсия верна, по крайней мере, в моей голове. Я даже не уверен, почему я подаю результат на Res.E
, так как в моем понимании, продолжение k
должно уже возвращать этот тип в любом случае.
Кроме того, я в настоящее время имею возвращения следующим образом (после Steve Horsfield):
let result v = Res.V v
Но также заметили, в некоторых должностях (особенно hilarious Frankenfunctor) это:
let result v = Res.E <| fun dc -> dc, Res.V v
Может быть, я следуя шаблону, которого я не должен был иметь, но в то время это казалось хорошей идеей, особенно в попытке реорганизовать zillions шаблона кода и заменить его на вычисления, но, возможно, мне следовало бы ick к прямой оценке, это подходило мне в голову;).
Но я чувствую, что я рядом ... Любые идеи?
В Haskell, когда вы хотите применить две монады одновременно, используется Monad Transformers. Я не уверен, что они доступны в F # (или если они даже реализованы - я сам не реализовал). Чтобы получить представление о концепции, я слышал статью [Monad Transformers Step by Step] (https://www.cs.virginia.edu/~wh5a/personal/Transformers.pdf). – paul
@paul, спасибо, я посмотрю. Но почему-то слишком сложно попросить одномерную реализацию для сохранения состояния __nd_ с его задержкой-оценкой. – Abel
есть проект github, который делает некоторые из них (я не могу найти его прямо сейчас, но я думаю, что он использует [FsControl] (https://github.com/gmpl/FsControl) - я уверен, что кто-то помнит его – Carsten