为什么可以';你为什么不写;(:)1[2]”;你写作的方式;"(x2B)1 2";在F#中?
将一个F#中缀运算符放在括号中,它的行为就像一个函数为什么可以';你为什么不写;(:)1[2]”;你写作的方式;"(x2B)1 2";在F#中?,f#,F#,将一个F#中缀运算符放在括号中,它的行为就像一个函数 让foo=(*)32//foo=6 让阶乘n=[2..n]|>List.fold(*)1//n! 但是,这不适用于::运算符(cons运算符) 原因是什么?因为(::)(以及[])是一个符号关键字,所以不能期望将其用作中缀运算符。请参见第3.6节“符号关键字” 在这种情况下,您必须定义一个额外的函数,例如 let cons x xs = x :: xs let ls = cons 1 [2..5] 您可以使用静态方法: let ls =
让foo=(*)32//foo=6
让阶乘n=[2..n]|>List.fold(*)1//n!
但是,这不适用于::运算符(cons运算符)
原因是什么?因为(::)
(以及[]
)是一个符号关键字,所以不能期望将其用作中缀运算符。请参见第3.6节“符号关键字”
在这种情况下,您必须定义一个额外的函数,例如
let cons x xs = x :: xs
let ls = cons 1 [2..5]
您可以使用静态方法:
let ls = List.Cons (1, [2..5])
或操作员的详细名称:
let ls = op_ColonColon (1, [2..5])
(使用F#3.0进行检查;旧版本可能会有不同的行为。例如,建议op#u Cons
)
在这两种情况下,都没有办法在这里讨好争论。数字运算符的定义如下:
let inline ( * ) (x:int) (y:int) = ...
但是,列表串联需要一个元组,这也回答了您的问题
这是什么原因
事实上,(:)
不是一个常用的操作符(独立函数或类型成员),而是一个联合大小写。下面是列表的运行方式=
|([]):'T列表
|(:):Head:'T*Tail:'T list->'T list
因此,如果您的目的是部分应用参数,那么唯一好的解决方案就是按照@pad的建议编写一个包装函数。非常好的一点-但问题不仅仅是union的情况(您可以用这种方式使用自己的构造函数-问题是我们没有这些构造函数的通用版本,因此需要(:)像一个人一样行动在F#库之外似乎有特殊的语法suggar(实际上,你甚至可能不使用这种定义(有点像GADTs;))
let inline ( * ) (x:int) (y:int) = ...
type List<'T> =
| ([]) : 'T list
| (::) : Head: 'T * Tail: 'T list -> 'T list