Nick Gilbert
Nick Gilbert

Reputation: 4240

F# Test if element is in list using List.Fold

I'm trying to write a function that takes a list and an element to look for in that list and returns true if the element is in the list and false otherwise. I want to use List.Fold to make the function much shorter. Right now it looks like this

let isInList(elementToFind, listToCheck) = 
    List.fold(fun(a, b) -> a=elementToFind or b), false, listToCheck;

However, I'm getting a syntax error at a=elementToFind or b saying that the expression was expected to have 'a -> 'b * 'c but has bool. I'm pretty new to F# and functional programming in general so any help I could get here would be greatly appreciated.

Upvotes: 0

Views: 579

Answers (3)

Functional_S
Functional_S

Reputation: 1159

When performance is needed you better use tryFind, because fold is non-short-circuit. That means if the list is 1 Mio. elements long and the first element is searched, the fold runs until the end of the list.

let isInList elementToFind listToCheck = 
    List.tryFind ((=) elementToFind) listToCheck

let x = [1;2;2;3]
let y = 4
let z = 2

isInList y x |> printfn "%A"    // None    
isInList z x |> printfn "%A"    // Some 2

Upvotes: 0

Jakub Lortz
Jakub Lortz

Reputation: 14896

Way too many parenthesis and comas in your code.

To declare a function that takes 2 parameters you should use

let f param1 param2 = ...

No parenthesis, no comas. If you define a function as

let f2 (param1, param2) = ...

you define a function that takes 1 argument, and this argument is a 2-element tuple.

Removing all comas and almost all parenthesis from the code will leave one more error - the parameters of the function you pass to List.fold are in wrong order.

let isInList elementToFind listToCheck = 
    List.fold(fun acc elem -> elem=elementToFind || acc) false listToCheck

You should also check the documentation of the List module. There are many useful functions there, for example List.exists

Upvotes: 1

FoggyFinder
FoggyFinder

Reputation: 2220

You can implement this using List.fold as follows:

let isInList elementToFind listToCheck = 
    List.fold(fun acc x -> acc || x = elementToFind) false listToCheck

Example:

let x = [1;2;2;3]
let y = 4
let z = 2

isInList y x |> printfn "%A"
isInList z x |> printfn "%A"

Print:

false
true

Link:

https://dotnetfiddle.net/6swKR5

Read more about List.fold

Upvotes: 1

Related Questions