Как использовать соответствующие элементы Map в F #? - PullRequest
0 голосов
/ 04 января 2019

Я попытался создать функцию, которая принимает два целых числа a, b в качестве входных данных и возвращает 5, если a = 1 b = 2 и 6 в противном случае. Вот что я сделал:

let examplef (a:int), (b:int)=
    match a,b with
    |1,2 -> 5
    |_,_->6;;

Это даетошибка: «Дискриминатор шаблона« examplef »не определен».

Я задаю этот вопрос из-за ошибки в этом коде:

type Team = string 
type Goals = Goals of int 
type Points = Points of int 
type Fixture = Team * Team 
type Result = (Team * Goals) * (Team * Goals) 
type Table = Map<Team,Points>

let league =["Chelsea"; "Spurs"; "Liverpool"; "ManCity"; "ManUnited"; "Arsenal"; "Everton"; "Leicester"]

let pointsMade (a: Result)=
    match a with
    |((b,Goals bg),(c,Goals cg))-> if b<c then ((b,Points 0),(c, Points 3))
                                   elif b=c then ((b,Points 1),(c,Points 1))
                                   else ((b, Points 3),(c, Points 0))

При попытке определитьследующая функция:

let updateTable (t:Table, r: Result)= 
    let pointmade = pointsMade r
    match pointmade with
    |((f,Points s),(f1,Points s1))-> match Map.tryFind f t  Map.tryFind f1 t with
                                    |None, None -> t
                                    |Some Points x, Some Points y ->t .Add (f, Points s+x1) .Add(f1, Points s1+y1)

При наведении курсора мыши на первый «Map.tryFind ft» он говорит: «Это значение не является функцией и не может быть применено. Также при t .Add (f, Points s+x1) .Add(f1, Points s1+y1) возникает ошибкав нем говорится: «Последовательные аргументы должны быть разделены пробелом и кортежами, а аргументы, включающие функции или приложения методов, должны быть заключены в скобки». Пожалуйста, помогите

Ответы [ 3 ]

0 голосов
/ 05 января 2019

В любом случае, код, который работает, выглядит следующим образом:

open System.Security.Cryptography
open System.Threading

type Team = string 
type Goals = Goals of int 
type Points = Points of int 
type Fixture = Team * Team 
type Result = (Team * Goals) * (Team * Goals) 
type Table = Map<Team,Points>

let league =["Chelsea"; "Spurs"; "Liverpool"; "ManCity"; "ManUnited"; "Arsenal"; "Everton"; "Leicester"]

let pointsMade (a: Result)=
    match a with
    |((b,Goals bg),(c,Goals cg))-> if bg<cg then ((b,Points 0),(c, Points 3))
                                   elif bg=cg then ((b,Points 1),(c,Points 1))
                                   else ((b, Points 3),(c, Points 0))

let initEntry (name:Team)=(name, Points 0) 

let initializeTable l = Map.ofList (List.map initEntry l)

let updateTable (t:Table, r: Result)= 
    let pointmade = pointsMade r
    match pointmade with
    |((f,Points s),(f1,Points s1))-> match Map.tryFind f t,  Map.tryFind f1 t with
                                     |None, None -> t
                                     |Some  x, Some  y-> match x,y with
                                                         | Points x1 , Points y1 -> t |> Map.add f (Points(x1+s)) |> Map.add f1 (Points (y1+s1))
                                     |None, Some y -> match y with 
                                                      | Points y1 -> t.Add(f,Points s) .Add(f1, Points (s1+y1))
                                     |Some x, None -> match x with 
                                                      | Points x1 -> t.Add(f,Points (s+x1)) .Add(f1, Points s1)       


let rec weekendUpdate (t:Table , rl:Result list)=
    match rl with
    |[]->t
    |ai::at-> weekendUpdate(updateTable(t,ai),at)

let rec seasonUpdate (t:Table, sll: Result list list)= 
    match sll with
    |[]->t
    |ah::at-> seasonUpdate(weekendUpdate(t,ah),at)

let less((s1,n1):Team * Points, (s2,n2):Team * Points) = 
    match n1,n2 with
    |Points m1,Points m2 ->if m1<m2 then true
                           else false

let rec myinsert item lst = 
    match lst with 
    | [] -> [item] 
    | x::xs -> if less(item,x) then x::(myinsert item xs) else item::lst                      

let rec isort lst = 
    match lst with 
    | [] -> [] 
    | x::xs -> myinsert x (isort xs)

let showStandings (t:Table) = isort (Map.toList t)
0 голосов
/ 05 января 2019

В вашем «рабочем коде», в функции pointsMade вам не нужно использовать сопоставление с образцом, вы можете просто использовать привязку let.

let pointsMade (r: Result) =
    let (t1, Goals g1), (t2, Goals g2) = r
    if g1 < g2 then (t1, Points 0), (t2, Points 3)
    elif g1 = g2 then (t1, Points 1), (t2, Points 1)
    else (t1, Points 3), (t2, Points 0)

Функцию updateTable также можно переписать более кратко, используя некоторую функцию addPoints, чтобы избежать повторения одного и того же для каждой команды.

let addPoints (team: Team, Points points) (table: Table) =
    match Map.tryFind team table with
    | None            -> table
    | Some (Points p) -> Map.add team (Points (points + p)) table

let updateTable (table: Table, result: Result) =
    let pts1, pts2 = pointsMade result
    table |> addPoints pts1 |> addPoints pts2
0 голосов
/ 04 января 2019

Похоже, вы путаете аргументы кортежа и карри.

Примеры с одним аргументом кортежа (требуются скобки).

signature: int * int -> int

//let example1 (a: int, b:int) = 
let example1 (a, b) =
    match a, b with
    | 1, 2 -> 5
    | _    -> 6

//let example2 (t: int * int) =
let example2 t =
    match t with
    | 1, 2 -> 5
    | _    -> 6 

Пример с двумя аргументами карри:

подпись: int-> int -> int

//let example3 (a: int) (b: int) = 
let example3 a b =
    match a, b with
    | 1, 2 -> 5
    | _    -> 6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...