Elm - 如何处理类型信号 Bool

Elm - How to process type 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)

当输入鼠标位置时,这可以计算鼠标是否在形状区域(由矩形区域近似):

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

其中 (width, height)(sX, sY) 的类型为 Signal.Signal (Float, Float)

这里的问题是上述表达式的返回值是 Signal Bool 类型——如何将其输入条件函数,如 if? 他们只接受 Bool 类型。

这里有我遗漏的最佳实践吗?

您需要使用 Signal.map 来处理信号持有的值。您的代码片段已经使用 Signal.map3 执行此操作(它被称为 map3 因为它接受三个不同的信号参数)。

当您使用 Signal.map 时,您的映射函数根本不需要处理信号。恰当的例子:您的 inPosInShape 函数处理原语而不考虑信号。

因此,如果你想对 isPosInShape 生成的信号做一些事情,你需要使用 Signal.map,并提供一个接受 Bool 并转换的函数它变成别的东西。

这是一个完全人为的例子,它作用于 Keyboard.space 信号的布尔值,类型为 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