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,但在第二種情況下,您使用強制進行更改的字符串。 –