Search code examples
elm

case-of with Random.Generate Int


I am new with elm. Elm version is 0.19. I am trying to use Ranndom.int to select ship type, but don't know how to do it. What should I do with the function numToShip? Change the type?

Here is my code ...

type ShipType
    = Battleship
    | Cruiser   
    | Destroyer 
    | Submarine 

numToShip : Int -> ShipType
numToShip num =
   case num of
     0 -> Destroyer
     1 -> Battleship
     2 -> Cruiser
     _ -> Submarine

shipName : ShipType -> String
shipName shipType =
  case shipType of
    Destroyer ->
        "Destroyer"
    Battleship ->
        "Battleship"
    Cruiser ->
        "Cruiser"
    Submarine ->
        "Submarine"

randomShip : String
randomShip =
  shipName (numToShip (Random.int 0 3) )

error message is:

The 1st pattern in this `case` causing a mismatch:

 146|   case num of

 147|>    0 -> Destroyer 

 148|     1 -> Battleship

 149|     2 -> Cruiser

 150|     _ -> Submarine

The first pattern is trying to match integers:
    Int

But the expression between `case` and `of` is:
    Random.Generator Int

These can never match! Is the pattern the problem? Or is it the expression?


Solution

  • Random.int does not return an Int, but a Generator Int. You'll then call Random.generate to turn that Generator into a Cmd, which will then call your update function with the generated value.

    One of the characteristics of Elm is that all functions are pure, meaning that the same inputs always result in the same outputs. Since you're asking for a different value each time you call the function, you need to hand that command off to the runtime, which can handle the impurity of the request (which is the same thing that happens when you want to communicate with the outside world via HTTP or JavaScript). See the Random example in the Elm Guide for more details.

    Alternatively, you can get a value immediately from the Generator if you are willing to supply a seed used to calculate the random value. You can use Random.step, which takes a Generator and a Seed, and produces a value and the next seed, which you can feed back into step if you need multiple values. You'll probably only want to do this if it's useful to be able to "replay" your random values, as it's kind of a pain to keep the Seed around. Otherwise, just stick with using generate to create a Cmd.