Reputation: 271
I tried to create a function that takes two integers a,b as input and return 5 if a=1 b=2 and 6 otherwise, Here is what I did:
let examplef (a:int), (b:int)=
match a,b with
|1,2 -> 5
|_,_->6;;
It gives this error: "The pattern discriminator 'examplef' is not defined."
I ask this question because of the error in this code:
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))
I get an error when trying to define the following function:
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)
When I hover the mouse over the first "Map.tryFind f t" It says "This value is not a function and cannot be applied. Also, there is an error with t .Add (f, Points s+x1) .Add(f1, Points s1+y1)
it says: "Successive arguments should be separated by space and tuples and arguments involving functions or method applications should be parenthesized".
Please help
Upvotes: 1
Views: 373
Reputation: 2493
In your "working code", in the pointsMade
function you do not need to use pattern matching, you can simply use a let binding.
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)
The updateTable
function also can be re-written in more concise way by using some addPoints
function to avoid repeating the same thing for each team.
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
Upvotes: 1
Reputation: 271
Anyway, The code that work looks like this:
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)
Upvotes: 1
Reputation: 2493
It looks like you're confusing tuple and curried arguments.
Examples with a single tuple argument (parenthesis are requiered).
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
Example with two curried arguments:
signature: int-> int -> int
//let example3 (a: int) (b: int) =
let example3 a b =
match a, b with
| 1, 2 -> 5
| _ -> 6
Upvotes: 1