1
我有两个文件。第一个文件,即所谓RailwayCombinator.fs的内容,分别是:当我在文件之间移动代码时,为什么类型会改变
module RailwayCombinator
let (|Uncarbonated|Carbonated|) =
function
| Choice1Of2 s -> Uncarbonated s
| Choice2Of2 f -> Carbonated f
let uncarbonated x = Choice1Of2 x
let carbonated x = Choice2Of2 x
let either successFunc failureFunc twoTrackInput =
match twoTrackInput with
| Uncarbonated s -> successFunc s
| Carbonated f -> failureFunc f
第二个文件,这就是所谓Program.fs的内容,分别是:
open RailwayCombinator
let carbonate factor label i =
if i % factor = 0 then
carbonated label
else
uncarbonated i
let fizzBuzz =
let carbonateAll =
carbonate 3 "Fizz" <+> carbonate 5 "Buzz"
carbonateAll
我也有一个代码块:
let (<+>) switch1 switch2 x =
match (switch1 x),(switch2 x) with
| Carbonated s1,Carbonated s2 -> carbonated (s1 + s2)
| Uncarbonated f1,Carbonated s2 -> carbonated s2
| Carbonated s1,Uncarbonated f2 -> carbonated s1
| Uncarbonated f1,Uncarbonated f2 -> uncarbonated f1
如果我把代码块放到名为Program的文件中,它就编译得很好。如果我把它放在RailwayCombinator中,我会在这条线上发现错误。
carbonate 3 "Fizz" <+> carbonate 5 "Buzz"
的错误是:
This expression was expected to have type
int
but here has type
string
我也注意到,根据其所在的文件< +>签名变了,但我不知道为什么签名改变。当它在RailwayCombinator的签名是:
val (<+>) :
switch1:('a -> Choice<'b,int>) ->
switch2:('a -> Choice<'c,int>) -> x:'a -> Choice<'b,int>
当它在程序上的签名改为
val (<+>) :
switch1:('a -> Choice<'b,string>) ->
switch2:('a -> Choice<'c,string>) -> x:'a -> Choice<'b,string>
那么,为什么签名变化?
猜测,标记函数内联可以解决这个问题,因为+的默认值是int,但在第二种情况下,您使用强制进行更改的字符串。 –