2016-03-31 8 views
0

Die folgende Funktion bestimmt, ob oder ob nicht eine bestimmte Position innerhalb einer Form zu verarbeiten:Elm - Wie Typ Signal Bool

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) 

wenn Mauspositionen zugeführt wird, kann dies berechnen, ob die Maus in einer Form ist, Region (durch ein Rechteck angenähert Region):

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

wo (width, height) und (sX, sY) sind vom Typ Signal.Signal (Float, Float).

Das Problem hier ist, dass der zurückgegebene Wert des obigen Ausdrucks vom Typ Signal Bool ist - wie kann dies in bedingte Funktionen wie if eingespeist werden? Sie würden nur Bool Typen akzeptieren.

Gibt es eine Best Practice, die mir hier fehlt?

Antwort

1

Sie müssen Signal.map verwenden, um den Wert des Signals zu verarbeiten. Ihr Code-Snippet macht genau das mit Signal.map3 (es heißt map3, weil es drei verschiedene Signalparameter akzeptiert). Wenn Sie Signal.map verwenden, muss Ihre Zuordnungsfunktion überhaupt nicht mit Signalen arbeiten. Ein Beispiel: Ihre inPosInShape-Funktion behandelt Primitive ohne Rücksicht auf Signale.

Deshalb, wenn Sie etwas mit dem Signal, das von isPosInShape erzeugt tun wollen, müssen Sie Signal.map, verwenden und eine Funktion zur Verfügung stellen, die ein Bool akzeptiert und verwandelt es in etwas anderes.

Hier ist ein völlig erfundenes Beispiel, die aus dem Keyboard.space Signal auf die boolean wirkt, die vom Typ ist 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