[F#] каррирование в методах и локальных функциях
От: Jack128  
Дата: 29.05.10 11:23
Оценка:
день добрый.

есть такой код:


module StringBuilder =
    let AddInt (value: int) (str: StringBuilder) = StringBuilder()
    let AddFloat (value: float) (str: StringBuilder) = StringBuilder()
    let AddNums addFunc (nums: seq<'a>) (str: StringBuilder) =
        nums |> Seq.fold (fun str n -> addFunc n str) str
    let AddInts1 = AddNums AddInt 
    let AddInts2 values = AddNums AddInt values

let SaveToCxemaDat rootFolder =
    let LocalAddInts = StringBuilder.AddNums StringBuilder.AddInt


()

метод AddInts1 не компилится с ошибкой

Error 1 Value restriction. The value 'AddInts1' has been inferred to have generic type val AddInts1 : ('_a -> StringBuilder -> StringBuilder) when '_a :> seq<int> Either make the arguments to 'AddInts1' explicit or, if you do not intend for it to be generic, add a type annotation. C:\Users\Женя\Documents\Visual Studio 2008\Projects\Project1\ConsoleApplication1\ConsoleApplication1\Program.fs 11 9 ConsoleApplication1



а вот абсолютно идентичная LocalAddInts вполне компилябельная. В чем разница?
Re: [F#] каррирование в методах и локальных функциях
От: Jack128  
Дата: 29.05.10 18:14
Оценка:
Здравствуйте, Jack128, Вы писали:

Я тут по эксперементировал, и пришел к такому выводу:
в общем случает каррирование для методов работает в следующем случае:

пусть метод let someMethod a1 (a2:T1<'a>) a3 (a4:T2<'a>)
так вот, если при карринге я зафиксировал хотя бы один аргумент зависящий от 'a — то я обязан, перечислить в сигнатуре все аргумент зависящие от 'a.
то есть

let someMethod2 = someMethod 10 — работает.
let someMethod3 = someMethod 10 (T1<int>()) — не работает, так как не зафиксирован a4
let someMethod4 a3 a4 = someMethod 10 (T1<int>()) a3 a4 = — работает

а с точки зрения теории есть объяснение, порму для методов такая странная логика идет, а для локальных функций карринг работает всегда?
Re[2]: [F#] каррирование в методах и локальных функциях
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.05.10 06:48
Оценка:
Здравствуйте, Jack128, Вы писали:

J>а с точки зрения теории есть объяснение, порму для методов такая странная логика идет, а для локальных функций карринг работает всегда?


Кажись есть такое что если не удается вывести конкретный тип из использования карированых функций, то компилятор просит явно указать тип функции или использовать аргументы.

Надо конечно спеку покурить по этому поводу и почитать Expret F# по этому поводу.
Re[3]: [F#] каррирование в методах и локальных функциях
От: Jack128  
Дата: 31.05.10 07:33
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Кажись есть такое что если не удается вывести конкретный тип из использования карированых функций, то компилятор просит явно указать тип функции или использовать аргументы.


да нет, вывод типов здесь не причем, ИМХО. Код то что для локальной функции, что для метода — одинаков. И потом — если я явно укажу аргументы, но не укажу их типов, то выводу типов это ничем не поможет.
Re: [F#] каррирование в методах и локальных функциях
От: achp  
Дата: 31.05.10 13:01
Оценка: 10 (2)
Здравствуйте, Jack128, Вы писали:

J>а вот абсолютно идентичная LocalAddInts вполне компилябельная. В чем разница?


Почему такое ограничение введено для значений на уровне модуля, описано тут:
http://blogs.msdn.com/b/mulambda/archive/2010/05/01/value-restriction-in-f.aspx

Для локальных значений соображения, там описанные, несущественны.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.