2014-01-12 4 views
1

Это работает в F # Interactive:добавляющим списки в лямбда

let (list:(int * int) List) = [] 
list @ [(40, 60)];; 

Эта doesent работы в моей программе:

let rMouseEvent = 
    form.MouseClick.Add(fun args -> list @ [(args.X, args.Y)])) 

Может кто-то объяснить, почему, и помочь мне решить эту проблему?

Ошибка говорит:
Это выражение, как ожидается, имеют тип
блок
, но здесь имеет тип
«список ->» список

+0

Что ошибка компиляции вы получите или что-то не удается ? –

+0

Извините, обновите сообщение. Это ошибка компиляции –

+0

Вы уверены, что это ошибка [я бы ожидал чего-то более похожего на жалобу, что у нее есть тип '(int * int) list']? Какое выражение оно выделяет? Диагноз в ответе Ли кажется, по сути, правильным. –

ответ

2

Ваш обработчик не должен возвращать значение, в настоящее время он возвращает int * int list. Вы можете игнорировать его с помощью игнорирования:

let rMouseEvent = form.MouseClick.Add(fun args -> list @ [(args.X, args.Y)] |> ignore) 

хотя это не очень полезно. Если вы хотите добавить элемент list, вы можете изменить его на ResizeArray:

let r = new ResizeArray<int * int>() 
let rMouseEvent = form.MouseClick.Add(fun args -> r.Add((args.X, args.Y))) 

в качестве альтернативы вы можете использовать реф:

let (r: (int*int) list ref) = ref [] 
let rMouseEvent = form.MouseClick.Add(fun args -> r := !r @ [(args.X, args.Y)]) 
+0

Почему это не полезно? А что такое ResizeArray по сравнению с этим способом? –

+3

@PontusMagnusson - Это не полезно, потому что вы создаете новый список и немедленно отбрасываете его. '@' создает новый список из двух входных списков, он не изменяет список аргументов. Если вы хотите изменить список, используйте 'ResizeArray'. – Lee

2

Ошибка компиляции вы получите указывает, что обработчик событий был Ожидается, что он вернется unit - то есть никакого значения вообще - но вы пытаетесь вернуть (int * int) list. Ожидаемый тип возвращаемого значения указывает на то, что вызывающий абонент не будет следить за возвращаемым вами значением, поэтому вам нужно сохранить любые значения, которые вы меняете сами.

Если вы хотите придерживаться с помощью списков, а затем сделать свой первоначальный список в ref:

let list : (int * int) List ref = ref [] 

, а затем сделать что-то вроде:

let rMouseEvent = 
    form.MouseClick.Add(fun args -> list := !list @ [(args.X, args.Y)])) 
Смежные вопросы