我已经在某个地方看到了(抱歉,我无法找到参考资料)这个运算符组合:
(>>)(>>)
其中(>>): (('a -> 'b) -> ('b -> 'c) -> 'a -> 'c)
- (>>)
为the function composition operator。
我发现更简单的例子很容易理解。例如(>>)f
,其中f: i -> i
。
(>>)(i -> i)
变为(i -> 't) -> i -> 't
。这是因为('a -> 'b)
被剔除,'b
被推断为i
而't
仍为通用类型。
我不完全理解(>>)(>>)
:
使用
(>>)(>>)
和(<<)(<<)
会用于什么?
为什么有必要使参数明确化?
> (>>)(>>);;
(>>)(>>);;
-^^^^^^
C:\Users\...\Temp\stdin(3,2): error FS0030: Value restriction. The value 'it' has been inferred to have generic type
val it : (((('_a -> '_b) -> '_c -> '_b) -> '_d) -> ('_c -> '_a) -> '_d)
Either make the arguments to 'it' explicit or, if you do not intend for it to be generic, add a type annotation.
根据错误消息的建议:
> let strangeFun arg = (>>)(>>) arg;;
val strangeFun : arg:((('a -> 'b) -> 'c -> 'b) -> 'd) -> (('c -> 'a) -> 'd)
答案 0 :(得分:1)
过去,有一些关于价值限制的解释; here是我写的,解释了为什么有必要。为了完整起见,我将在此复制示例代码,如果删除了值限制,则该代码将不正确:
let f : 'a -> 'a option =
let r = ref None
fun x ->
let old = !r
r := Some x
old
f 3 // r := Some 3; returns None : int option
f "t" // r := Some "t"; returns Some 3 : string option!!!
至于(>>)(>>)
将用于什么,我承认我不知道。然而,有一个看起来相似但有用的函数,它是(<<) << (<<)
(在Haskell中更为人所知的(.).(.)
),它返回一个类似的合成运算符,其第二个和返回的函数可以取 2 参数而不是一个。
let (<<<<) f = ((<<) << (<<)) f;;
// val ( <<<< ) : f:('a -> 'b) -> (('c -> 'd -> 'a) -> 'c -> 'd -> 'b)