category
category

Reputation: 2155

Elm - How to process type Signal Bool

The following function determines whether or not a given position is inside a shape:

isPosInShape: (Int,Int) -> (Float,Float) -> (Float,Float) -> Bool
isPosInShape (posX, posY) (w, h) (shapeX, shapeY) =
  let
    (pX,pY) =
      (toFloat posX, toFloat posY)
  in
    (pX > shapeX - w/2) && (pX < shapeX + w/2) && (pY > shapeY - h/2) && (pY < shapeY + h/2)

when fed Mouse positions, this can calculate whether or not the mouse is in a shape region (approximated by a rectangle region):

Signal.map3 isPosInShape Mouse.position (width, height) (sX, sY)

where (width, height) and (sX, sY) are of type Signal.Signal (Float, Float).

The issue here is that the returned value of the above expression is of type Signal Bool - how can this be fed into conditional functions like if? They would only accept Bool types.

Is there a best practice that I'm missing here?

Upvotes: 0

Views: 110

Answers (1)

Chad Gilbert
Chad Gilbert

Reputation: 36375

You'll need to use Signal.map to process the value held by the signal. Your code snippet is already doing just that with Signal.map3 (it's called map3 because it accepts three different signal parameters).

When you use Signal.map, your mapping function doesn't need to deal with Signals at all. Case in point: your inPosInShape function deals with primitives without respect to Signals.

Therefore, if you want to do something with the signal generated by isPosInShape, you'll need to use Signal.map, and provide a function that accepts a Bool and turns it into something else.

Here's a completely contrived example which acts on the boolean from the Keyboard.space signal, which is of type Signal Bool:

import Graphics.Element exposing (show)
import Keyboard

doSomething : Bool -> String
doSomething b =
  if b then
    "The spacebar is pressed!"
  else
    "Please press the spacebar!"

main = Signal.map (show << doSomething) Keyboard.space

Upvotes: 1

Related Questions