#f#
#f#
Вопрос:
Может ли кто-нибудь пояснить, почему я получил это сообщение (см. Комментарий в двух строках ниже), и, возможно, указать на правильную спецификацию определяемых пользователем двоичных операторов. Почему я должен определять оператор (.—gt;.) вне определения типа и и не (.gt;gt;gt;gt;gt;=.)?
type ListAlt;'Tgt; = NIL | Cons of 'T * ListAlt;'Tgt; with static member cat (a:ListAlt;'Tgt;) (b:ListAlt;'Tgt;) :ListAlt;'Tgt;= match a with | NIL -gt; b | Cons (a, tail) -gt; Cons (a, (ListAlt;'Tgt;.cat tail b)) static member join (a:ListAlt;ListAlt;'Tgt;gt;) = match a with | NIL -gt; NIL | Cons (a, b) -gt; ListAlt;'Tgt;.cat a (ListAlt;'Tgt;.join b) static member fmap (fn: 'T -gt; 'U) (a:ListAlt;'Tgt;) = match a with | NIL -gt; NIL | Cons (a, tail) -gt; Cons ((fn a), (ListAlt;'Tgt;.fmap fn tail)) static member inline (.gt;gt;=.)(ma:ListAlt;'Tgt; , k:'T -gt; ListAlt;'Ugt;) = ListAlt;'Tgt;.fmap k ma |gt; ListAlt;_gt;.join static member inline (.lt;lt;lt;.)(mbc:'B -gt; ListAlt;'Cgt; , mab:'T -gt; ListAlt;'Bgt;) = (fun x -gt; (mab x) .gt;gt;=. mbc) static member inline (.gt;gt;gt;.)(mab:'T -gt; ListAlt;'Bgt; , mbc:'B -gt; ListAlt;'Cgt;) = (fun x -gt; (mab x) .gt;gt;=. mbc) static member join2 (a:ListAlt;_gt;) = a .gt;gt;=. id let (.--gt;.)(mab:'T -gt; ListAlt;'Bgt;) (mbc:'B -gt; ListAlt;'Cgt;) = (fun x -gt; (mab x) .gt;gt;=. mbc) let (.lt;--.)(mab:'B -gt; ListAlt;'Cgt;) (mbc:'T -gt; ListAlt;'Bgt;) = (fun x -gt; (mbc x) .gt;gt;=. mab) let f = fun x -gt; Cons (x, Cons ((x 1), NIL)) let g = fun x -gt; Cons (x * 2, NIL) // NOT Compiling: let fgA = fun x -gt; (f .lt;lt;lt;. g) // NOT Compiling: let fgB = fun x -gt; (f .gt;gt;gt;. g) let fg = fun x -gt; (f x) .gt;gt;=. g let fg1 = (f .--gt;. g .--gt;. g) let fg2 = (f .lt;--. g .--gt;. f) printfn "%A" (fg1 3)
Ответ №1:
Таковы правила поиска операторов. Сначала (1) компилятор пытается определить, определен ли оператор как метод для одного из типов операндов, а затем (2) он пытается просмотреть текущий лексический контекст (т. е. текущий модуль и любые open
модули ed).
(кстати, правило (1) является общим для всех .NET, в то время как правило (2) относится только к F#)
.gt;gt;=.
работает, потому что он определен по типу своего первого аргумента (f x)
, поэтому применяется правило (1).
.--gt;.
работает, потому что это определено в текущем контексте, поэтому применяется правило (2).
Но в выражении f .gt;gt;gt;. g
тип обоих аргументов является функцией 'a -gt; ListAlt;'agt;
, и в этом типе оператор не .gt;gt;gt;.
определен как метод, и .gt;gt;gt;.
в текущем контексте оператор не определен, поэтому ни правило (1), ни правило (2) не применяются, и компилятор понятия не имеет, где искать этот оператор.
Комментарии:
1. Отличный ответ. Очень полезно
2. Если мой ответ помог вам, пожалуйста, подумайте о том, чтобы «принять» его. Вы можете сделать это, щелкнув бледно-серую галочку слева-это ответ.