Dan Rino Lauritzen
Dan Rino Lauritzen

Reputation: 392

How to check if list contains discriminated union case with type?

Given the follwing code:

type Creature = 
    { Strength: int 
      Toughness: int }

type CardType = 
    | Creature of Creature
    | Land 
    | Instant

type Card = 
    { Types: CardType list }
module Card = 
    let isType t card = List.contains t card.Types


I am able to write

Card.isType Land

When trying to check if card is a creature, i get the following error:

This expression was expected to have type
    'CardType'    
but here has type
    'Creature -> CardType'

Is it even possible to have a "isType" function like this or am I stuck with pattern matching on a separate "isCreature" function instead?

Upvotes: 2

Views: 97

Answers (1)

Tomas Petricek
Tomas Petricek

Reputation: 243096

Unless you want to resort to various reflection-based hacks, you are stuck with pattern matching. I would probably define a bit more general function using List.exist rather than List.contains (taking a predicate). Then you can easily define three functions for your specific card types:

module Card = 
  let isType t card = 
    List.exists t card.Types
  
  let isCreature = 
    isType (function Creature _ -> true | _ -> false)
  let isLand = isType ((=) Land)
  let isInstant = isType ((=) Instant)

For Land and Instant, you can just check if the value equals the specific one you're looking for. For Creature, this requires pattern matching - but can be done quite nicely using function.

Upvotes: 4

Related Questions