2016-11-15 3 views
1

Я создал функцию, которая принимает список и список списков и возвращает новый список списков.F # функция как аргумент в функции совпадения

let rec calculator list SS = 
    match (List.item(0) SS) with 
    |[] -> [] 
    |_ -> match (validate list (List.item(0) SS)) with 
     |(validate theCode list) -> List.append [(List.item(0) SS)] (calculator list (SS.[1..])) 
     |_ -> (calculator list (SS.[1..])) 

validate - это функция, которая возвращает два набора intup. Пример (1,1)

список представляет собой список из четыре Интса

SS является список списков с четыре Интсом

theCode является список из четыре Интса

я получаю сообщение об ошибке " Дискриминатор шаблона «проверять» не определен ».

Возможно, это глупый вопрос, но тем не менее я не знаю ответа на него.

Нельзя ли использовать функцию в качестве аргумента в выражении соответствия. Или это совсем другое происходит здесь?

Насколько я знаю, две функции проверки возвратят два набора intup и, следовательно, должны быть в состоянии соответствовать этому.

+4

Я думаю, что вы хотите, активный образец здесь –

+0

* "Validate функции тх t возвращает два чередующихся ints. "* Предполагая, что функция проверяет некоторый ввод, что она возвращает, когда вход действителен? Что он возвращает, когда вход недействителен? –

+2

Чтобы это скомпилировать, замените '| (проверьте список кодов) ->' с '| x, когда x = (проверьте список Code) -> '.Но, как пояснил @JohnPalmer, это просто уродливо - даже если «если ...» было бы чище здесь. – ildjarn

ответ

4

Если ваш вопрос заключается в том, чтобы получить эту компиляцию, то вам нужно только небольшое изменение – вызов функции не сам шаблон, так что вам нужно привязать к значению и использовать when guard:

let rec calculator list SS = 
    match (List.item(0) SS) with 
    | [] -> [] 
    | _ -> 
     match (validate list (List.item(0) SS)) with 
//  vvvvvvvvvv 
     | x when x = (validate theCode list) -> 
      List.append [(List.item(0) SS)] (calculator list (SS.[1..])) 
     | _ -> (calculator list (SS.[1..])) 

Однако, если ваш вопрос действительно «, то какой из них является предпочтительным» », то пока это слишком субъективно для этого сайта (IMO), я отправлю это как вариант, который я считаю идеально читаемым по этой логике:

let rec calculator list (h::t) = 
    if List.isEmpty h then h 
    elif validate list h = validate theCode list then h::(calculator list t) 
    else calculator list t 

(Это предполагает, что SS является F # список и не System.Collections.Generic.List.)

+0

Большое вам спасибо. – Nulle

+2

Просто примечание: было бы более обычным иметь 'h :: calculator list t' для добавления одного элемента в список, чем для создания нового списка одного элемента только для добавления списка. –

+0

@ Джейк Лишман: Действительно! Я был сосредоточен на том, чтобы отказаться от «матча» и не продумал все остальное полностью (по-видимому). Отредактировано, спасибо. – ildjarn

4

Это на самом деле не является ответом на вопрос о том, как реализовать when охрану, так как @ildjarn answered, что для вас.

Думаю, вам действительно будет лучше служить функция библиотеки. Вы пытаетесь отфильтровать элементы, которые не проходят проверку, но также останавливаются на первом пустом элементе. Если вы можете гарантировать, что вы определенно хотите перебрать каждый элемент SS, вы могли бы просто сделать

let calculator list = List.filter (fun s -> validate list s = validate theCode list) 

Если это вы должны остановиться на пустом элементе, можно определить функцию, которая разрежет список на первом пустом элемент, что-то вроде

let upToElement element list = 
    let rec loop acc = function 
     | [] -> List.rev acc 
     | h :: t when h = element -> List.rev acc 
     | h :: t -> loop (h :: acc) t 
    loop [] list 

, то вы можете сделать

let calculator list = 
    upToElement [] >> List.filter (fun s -> validate list s = validate theCode list) 
+0

Спасибо вам большое! Я намерен просто отфильтровать любой элемент, который не проходит проверку. Поэтому я обязательно займусь вашим решением List.filter! – Nulle

Смежные вопросы