2014-11-03 83 views
1

从一个榆树新手但长期哈斯克勒,一个快速查询。榆树信号和类型注释

目的:有一个地图上有指定位置的城镇,我想检查用户点击是否靠近一个城镇,并确定该城镇。

所以,我收集信号如常:

clickPositionsSignal = sampleOn Mouse.clicks Mouse.position 

这给了我一个元组,这是我想变成一个Int(表示最近的城镇的数量)。城镇被指定为

positions : [Position] 
type Position = {number : Int, x : Int, y : Int} 

功能来做到这一点:

whichTown : (Int,Int) -> Int 
whichTown (x,y) = 
      let pz = map (\p -> getDistance p.x p.y x y) positions |> head 
      in pz.number 

现在,我需要这个功能适用于我clickPositionsSignal。

放眼望去各种例子,我修改一些代码....

whichLocationSignal : Signal Int 
whichLocationSignal =   
     let wbl (x,y) = whichTown(x,y) 
     in wbl <~ clickPositionsSignal 

....这一点也适用。我得到最近的城镇的号码。

但这是绝望的繁琐和重复。问题是,为什么我不能简单地写:

whichLocationSignal = whichTown clickPositionsSignal 

那行抛出了多种类型的错误,我感到没有足够的经验来解释

+0

'whichBoardPosition'函数是什么样的? – rzetterberg 2014-11-03 07:30:59

+0

对不起,忘了将最后2个代码块中的函数从'whichBoardPosition'重命名为'whichTown'。上面编辑的代码。 – 2014-11-03 09:08:11

+0

啊。这很简单:whichTown <〜clickPositionsSignal – 2014-11-03 11:37:55

回答

1

TL; DR

它应该是:

whichLocationSignal = whichTown <~ clickPositionsSignal 

whichLocationSignal = lift whichTown clickPositionsSignal 

(你已经想通了,你自己)

如何阅读类型错误

所以你的代码的完整版本,让这些类型的错误是:

import Mouse 

type Position = {number : Int, x : Int, y : Int} 

clickPositionsSignal : Signal (Int,Int) 
clickPositionsSignal = sampleOn Mouse.clicks Mouse.position 

positions : [Position] 
positions = [] 

getDistance x1 y1 x2 y2 = { number = 0 } 

whichTown : (Int,Int) -> Int 
whichTown (x,y) = 
    let pz = map (\p -> getDistance p.x p.y x y) positions |> head 
    in pz.number 

whichLocationSignal : Signal Int 
whichLocationSignal = whichTown clickPositionsSignal 

类型错误我然后得到的是:

Type error on line 19, column 33 to 53: 
    clickPositionsSignal 

    Expected Type: (Int, Int) 
    Actual Type: Int 

Type error on line 19, column 33 to 53: 
    clickPositionsSignal 

    Expected Type: Signal.Signal 
    Actual Type: (Int) 

Type error on line 19, column 23 to 32: 
    whichTown 

    Expected Type: Int 
    Actual Type: Signal.Signal Int 

我承认,这些类型的错误令人困惑。
(你甚至可以说他们是不正确的,我只能说这是你获得的错误类型的当前质量,对不起!)
当Elm的类型错误没有意义时,一个基本的提示是以查看在翻转预期/实际时是否更有意义。那么第一种类型的错误是没有意义的。但第二个给出了一些信息:clickPositionsSignal预计有一个类型Int,而不是一些Signal。再加上第三条错误信息,这开始有意义:whichTown做了相反的事情,在Int应该给予,但你得到一个Signal ...
在这一点上,你可以一起找到这两者的用途,一旦你注意到whichTown适用于(Int,Int)clickPositionsSignal : Signal (Int,Int),你发现你的错误和编译器消息有一些歪曲的感觉。

如上所述的修复方法是使用lift : (a -> b) -> Signal a -> Signal b将功能“”“提升”为Signal“级别”。大多数人更喜欢使用中缀操作符<~

+0

感谢您的额外澄清。在我看来,预期/实际类型错误似乎(正如你注意到的)与我在Haskell期望的类似错误相反。 – 2014-11-04 12:31:50