了解 Haskell 中的这种类型?
Understanding this type in Haskell?
我在理解这种类型声明的工作原理时遇到了一些问题。
类型是:(a -> b) -> (b -> c) -> (c -> d) -> a -> d
所以,对我来说,我将其解释为一个接受函数的函数,而该函数接受另一个输出值 d 的函数。
所以,这就是我制作函数的方式:
Example :: (a -> b) -> (b -> c) -> (c -> d) -> a -> d
Example f g h x = f ( g ( h (x) )
如果你们能帮我澄清一下,我将不胜感激。谢谢!
我认为你已经知道你正在写的类型背后的理论,所以我会尝试注入一些直观的方式来阅读它(至少我希望如此,你的问题对我来说并不完全清楚) .
如您所说,当您在类型中读取类似 (a -> b) 的内容时,它就是一个函数。例如 (Int -> Bool) 是一个函数。
举个例子:
even :: Int -> Bool -- A more generic version of that is in the Prelude
even n = n `rem` 2 == 0
filter :: (Int -> Bool) -> [Int] -> [Int] -- And of that, too
filter _ [] = []
filter f (x:xs)
| f x = x : filter f xs
| otherwise = filter f xs
filteredEven :: [Int]
filteredEven = filter even [1..5] -- it gives [2, 4]
在这个例子中,我们有一个 "high order function",一个获取另一个函数并以某种方式使用它的函数。
在您定义的函数中,您只需使用 3 个函数(和另一个参数)。但你可以了解更多。
您在该类型中声明的每个函数都接受一个 return 前一个函数的值。所以一个可能的解决方案是你已经展示的那个。但是类型是通用的。没有一个 return 是通用值的总函数(其中 total 意味着它总是终止 returning 一个不同于底部的值,如果所有值都是总的并且底部不同,所以它不会例如崩溃或 return 未定义)。所以,如果你想要一个完整的函数,你必须有一种方法来从函数的上下文(它们的参数)中生成请求的变量。
在前面的示例中,使用您使用的名称,您必须 return 类型 d 的值。您只有一种方法可以生成该类型的值,即 h 函数。但是要使用 h 函数,您必须获得类型为 c 的值。你只有 g 功能。但是你需要一个 c 类型的值。幸运的是,你有函数 f,它用 a returns 类型的值来交换所需的值。我们有这个值(并且没有任何其他方法可以获得该类型的值),因此可以编写函数。我们不能以任何方式改变获得的值(多次调用函数不起作用,因为纯度和我们只有一种方法来产生值的事实),所以这是构造函数的唯一方法,如果我们希望它是完整的:
Example (a -> b) -> (b -> c) -> (c -> d) -> a -> d
Example f g h x = h (g (f x)))
我们可以用很多其他方式来写这个函数,但是它们给出的结果总是一样的(如果Example,f,g,h是total,x不是bottom)。所以类型可以很好地表达功能,因为我们只看类型就可以理解功能是如何工作的!
我在理解这种类型声明的工作原理时遇到了一些问题。
类型是:(a -> b) -> (b -> c) -> (c -> d) -> a -> d
所以,对我来说,我将其解释为一个接受函数的函数,而该函数接受另一个输出值 d 的函数。
所以,这就是我制作函数的方式:
Example :: (a -> b) -> (b -> c) -> (c -> d) -> a -> d
Example f g h x = f ( g ( h (x) )
如果你们能帮我澄清一下,我将不胜感激。谢谢!
我认为你已经知道你正在写的类型背后的理论,所以我会尝试注入一些直观的方式来阅读它(至少我希望如此,你的问题对我来说并不完全清楚) .
如您所说,当您在类型中读取类似 (a -> b) 的内容时,它就是一个函数。例如 (Int -> Bool) 是一个函数。
举个例子:
even :: Int -> Bool -- A more generic version of that is in the Prelude
even n = n `rem` 2 == 0
filter :: (Int -> Bool) -> [Int] -> [Int] -- And of that, too
filter _ [] = []
filter f (x:xs)
| f x = x : filter f xs
| otherwise = filter f xs
filteredEven :: [Int]
filteredEven = filter even [1..5] -- it gives [2, 4]
在这个例子中,我们有一个 "high order function",一个获取另一个函数并以某种方式使用它的函数。
在您定义的函数中,您只需使用 3 个函数(和另一个参数)。但你可以了解更多。
您在该类型中声明的每个函数都接受一个 return 前一个函数的值。所以一个可能的解决方案是你已经展示的那个。但是类型是通用的。没有一个 return 是通用值的总函数(其中 total 意味着它总是终止 returning 一个不同于底部的值,如果所有值都是总的并且底部不同,所以它不会例如崩溃或 return 未定义)。所以,如果你想要一个完整的函数,你必须有一种方法来从函数的上下文(它们的参数)中生成请求的变量。
在前面的示例中,使用您使用的名称,您必须 return 类型 d 的值。您只有一种方法可以生成该类型的值,即 h 函数。但是要使用 h 函数,您必须获得类型为 c 的值。你只有 g 功能。但是你需要一个 c 类型的值。幸运的是,你有函数 f,它用 a returns 类型的值来交换所需的值。我们有这个值(并且没有任何其他方法可以获得该类型的值),因此可以编写函数。我们不能以任何方式改变获得的值(多次调用函数不起作用,因为纯度和我们只有一种方法来产生值的事实),所以这是构造函数的唯一方法,如果我们希望它是完整的:
Example (a -> b) -> (b -> c) -> (c -> d) -> a -> d
Example f g h x = h (g (f x)))
我们可以用很多其他方式来写这个函数,但是它们给出的结果总是一样的(如果Example,f,g,h是total,x不是bottom)。所以类型可以很好地表达功能,因为我们只看类型就可以理解功能是如何工作的!