Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F#,从相对于IIInputElement的鼠标光标位置提取网格坐标_F# - Fatal编程技术网

F#,从相对于IIInputElement的鼠标光标位置提取网格坐标

F#,从相对于IIInputElement的鼠标光标位置提取网格坐标,f#,F#,如果我有一个任意大小的正方形网格(用WPF/XAML创建),每边有给定数量的单元格,那么通过获取鼠标光标相对于网格元素的位置来计算单击的单元格的坐标应该非常容易。当我尝试学习F#时,我遇到了一些语法问题,希望您能提供一些帮助 下面是我正在尝试做的一个例子: // From a mouse event, fetch the position of the cursor relative to a IInputElement let get_mouse_position (rela

如果我有一个任意大小的正方形网格(用WPF/XAML创建),每边有给定数量的单元格,那么通过获取鼠标光标相对于网格元素的位置来计算单击的单元格的坐标应该非常容易。当我尝试学习F#时,我遇到了一些语法问题,希望您能提供一些帮助

下面是我正在尝试做的一个例子:

    // From a mouse event, fetch the position of the cursor relative to a IInputElement 
    let get_mouse_position (relative_to : IInputElement) (args : Input.MouseEventArgs) : (int*int) = 
        let position = args.GetPosition relative_to 
        ((Convert.ToInt32(position.X) / cellsPerSide), (Convert.ToInt32(position.Y) / cellsPerSide))

    // Get the position of the cursor relative to the grid 
    let get_cell_coordinates (element : IInputElement) =
        get_mouse_position element
但是,当我尝试使用通过调用get_cell_coordinates检索到的坐标时,在其他需要(x,y)坐标的地方,我得到一个错误,该错误表示:

此表达式的类型应为int*int,但此处的类型为'a->int*int


那么,我做错了什么?为什么我得到的是这种变形类型而不仅仅是一组整数?

我通过使用static Mouse.GetPosition方法来获得鼠标的位置,而不是Input.MouseEventArgs

如果其他人有相同的问题,代码如下所示:

    // From a mouse event, fetch the position of the cursor relative to a IInputElement 
let get_mouse_position (relative_to : IInputElement) : (int*int) = 
    let position = Mouse.GetPosition relative_to
    ((Convert.ToInt32(position.X) / cellsPerSide), (Convert.ToInt32(position.Y) / 32))

// Get the position of the cursor relative to the input element
let get_cell_coordinates (element : IInputElement) =
    get_mouse_position element

我通过使用static Mouse.GetPosition方法来获得鼠标的位置,而不是Input.MouseEventArgs来解决这个问题

如果其他人有相同的问题,代码如下所示:

    // From a mouse event, fetch the position of the cursor relative to a IInputElement 
let get_mouse_position (relative_to : IInputElement) : (int*int) = 
    let position = Mouse.GetPosition relative_to
    ((Convert.ToInt32(position.X) / cellsPerSide), (Convert.ToInt32(position.Y) / 32))

// Get the position of the cursor relative to the input element
let get_cell_coordinates (element : IInputElement) =
    get_mouse_position element
您得到的类型不是“变形”类型,而是函数类型。之所以得到类型为
'a->int*int
的函数而不是预期的
int*int
结果,是因为没有将所有参数传递给函数,因此F#返回了预期其余参数的函数。这称为“部分应用程序”,您可以在此处了解更多信息:

两篇文章的简要总结:在F#中,所有函数都被视为接受一个参数并返回一个结果。是的,所有功能。当您创建一个似乎包含两个参数的函数时,F#会在内部重写它。它变成一个函数,接受一个参数并返回第二个函数;第二个函数接受一个参数并返回结果。在这一点上,一个具体的例子可能是有用的。考虑这个函数:

let doubleAndSubtract a b = (a * 2) - b
(显然,
a*2
周围的括号实际上是不需要的,但我保留了它们,以使函数清晰易读)

在内部,F#实际上将此函数重写为以下内容:

let doubleAndSubtract a =
    let subtract b = (a * 2) - b
    subtract
换句话说,它构建了一个函数,用于“关闭”(捕获)您传入的
a
的值。因此,以下两个函数是完全等效的:

let explicitSubtract b = (5 * 2) - b
let implicitSubtract = doubleAndSubtract 5
如果在F#交互式提示符中键入这些函数并查看它声明每个函数的类型,
explicitSubtract
具有type
b:int->int
,而
implicitSubtract
具有type
int->int
。这两者之间的唯一区别是
explicitSubtract
的类型命名参数,而
implicitSubtract
不“知道”其参数的名称。但两者都将取一个int,并返回一个int(具体来说,10减去参数)

现在,让我们看看
double和subtract的类型签名。如果你在F#交互式提示符中输入它,你会看到它的类型签名是
int->int->int
。在类型签名中,
->
是右关联的,因此签名实际上是
int->(int->int)
--换句话说,一个函数接受一个int并返回一个函数,这个函数接受一个int并返回一个int。但是你也可以把它看作是一个接受两个int并返回一个int的函数,你可以这样定义它

因此,您的代码在这里的情况是,您定义了如下函数:

let get_mouse_position (relative_to : IInputElement) (args : Input.MouseEventArgs) : (int*int) = ...
这是一个函数,它接受两个参数(类型分别为
IInputElement
Input.MouseEventArgs
)并返回一个整数元组但是这相当于一个函数,它接受一个类型为
IIInputElement
的参数,并返回一个接受
输入的函数。MouseEventArgs
并返回两个整数的元组。换句话说,您的函数签名是:

IInputElement -> Input.MouseEventArgs -> (int * int)
当您将其称为
get\u mouse\u position element
时,只传递了一个参数,因此得到的是
Input.MouseEventArgs->(int*int)
类型的函数。类型检查器将其报告为type
'a->int*int
(将
Input.MouseEventArgs
更改为泛型类型名
'a
),原因是我不想在这里讨论(这已经很长了),但这就是为什么您得到了结果

我希望这能帮助你更好地理解F#函数。阅读我链接的那两篇文章;他们会让你的理解更进一步。

你得到的类型不是“变形”类型,而是函数类型。之所以得到类型为
'a->int*int
的函数而不是预期的
int*int
结果,是因为没有将所有参数传递给函数,因此F#返回了预期其余参数的函数。这称为“部分应用程序”,您可以在此处了解更多信息:

两篇文章的简要总结:在F#中,所有函数都被视为接受一个参数并返回一个结果。是的,所有功能。当您创建一个似乎包含两个参数的函数时,F#会在内部重写它。它变成一个函数,接受一个参数并返回第二个函数;第二个函数接受一个参数并返回结果。在这一点上,一个具体的例子可能是有用的。考虑这个函数:

let doubleAndSubtract a b = (a * 2) - b
(显然,
a*2
周围的括号实际上是不需要的,但我保留了它们,以使函数清晰易读)

在内部,F#实际上将此函数重写为以下内容:

let doubleAndSubtract a =
    let subtract b = (a * 2) - b
    subtract
换句话说,它构建了一个“关闭ove”的函数