理解此表达式的Haskell类型
我在做哈斯凯尔式的练习,这一次让我很难堪。提供的表达式是:理解此表达式的Haskell类型,haskell,Haskell,我在做哈斯凯尔式的练习,这一次让我很难堪。提供的表达式是: f2 f g h = h.g.f f2的类型显然是: f2 :: (a -> b1) -> (b1 -> b) -> (b -> c) -> a -> c 对于这样一个简短的表达来说,这似乎过于复杂了。有人能解释一下为什么这作为类型是有意义的吗?我发现这些“确定某某表达式的类型”通常有点倒退。类型应该始终放在第一位:如果您想为某项任务编写解决方案,您可以将问题描述表述为类型签名。然后您继续实
f2 f g h = h.g.f
f2的类型显然是:
f2 :: (a -> b1) -> (b1 -> b) -> (b -> c) -> a -> c
对于这样一个简短的表达来说,这似乎过于复杂了。有人能解释一下为什么这作为类型是有意义的吗?我发现这些“确定某某表达式的类型”通常有点倒退。类型应该始终放在第一位:如果您想为某项任务编写解决方案,您可以将问题描述表述为类型签名。然后您继续实际编写一个实现 在本例中,您将从问题开始:我有三个函数
f
、g
和h
,以及一个类型的值,我可以传递给f
。此外,函数具有成对匹配的结果/参数类型。因此签字
f2 :: (α -> β) -> (β -> γ) -> (γ -> δ) -> α -> δ
您现在可以继续并以显式的指向形式实现它,即
f2 f g h x = h (g (f x))
这仍然很简短。毕竟,这是一项相当简单的任务
但是在Haskell中,您可以使用标准合成操作符
,将其缩短。最终实现非常短的事实基本上可以归结为这样一个事实:f2
基本上做了与
相同的事情,只做了两次。因此,如果您有一个具有复杂类型签名的非常复杂的任务,但发现某个库包含一个几乎可以完成该任务的函数,那么这并不比这更令人惊讶。显然,调用ready build函数将使您的实现比任务复杂度所建议的要短得多,但复杂度仅取决于库函数。我发现这些“确定某某表达式的类型”通常有点落后。类型应该始终放在第一位:如果您想为某项任务编写解决方案,您可以将问题描述表述为类型签名。然后您继续实际编写一个实现
在本例中,您将从问题开始:我有三个函数f
、g
和h
,以及一个类型的值,我可以传递给f
。此外,函数具有成对匹配的结果/参数类型。因此签字
f2 :: (α -> β) -> (β -> γ) -> (γ -> δ) -> α -> δ
您现在可以继续并以显式的指向形式实现它,即
f2 f g h x = h (g (f x))
这仍然很简短。毕竟,这是一项相当简单的任务
但是在Haskell中,您可以使用标准合成操作符
,将其缩短。最终实现非常短的事实基本上可以归结为这样一个事实:f2
基本上做了与
相同的事情,只做了两次。因此,如果您有一个具有复杂类型签名的非常复杂的任务,但发现某个库包含一个几乎可以完成该任务的函数,那么这并不比这更令人惊讶。显然,调用现成的构建函数将使您的实现比任务复杂度所建议的要短得多,但复杂度仅仅取决于库函数。为什么您认为它很复杂?它只是一个接受三个函数(匹配类型)并返回一个新函数的函数
为了保持一致性,我已将b1
重命名为b
,并更新了其他名称。下面是一个略加编辑的版本:
f2::(a->b)->(b->c)->(c->d)->a->d
- 这里,
接受类型为f2
的a->b
。也就是说,它是一个函数,具有某种类型的输入f
(a
可以是任何东西,这里没有限制)和某种类型的返回值a
b
- 然后
获取f2
哪个输入的类型必须匹配g
的输出,因此它是f
。它不能像b->c
(其中e->c
与e
不同),或者代码没有意义,因为它不可能组成b
f。g
- 对于第三个参数,
,类型为h
,情况也完全相同c->d
- 函数合成的结果(f2返回的内容)是一个新函数,它接受f所做的任何事情,并返回h返回的任何事情,因此它是
。通过这个,我们已经涵盖了整个类型定义a->d
基本上,这是一个相对较长的定义,但我认为它的本质非常简单。为什么你认为它很复杂?它只是一个接受三个函数(匹配类型)并返回一个新函数的函数 为了保持一致性,我已将
b1
重命名为b
,并更新了其他名称。下面是一个略加编辑的版本:
f2::(a->b)->(b->c)->(c->d)->a->d
- 这里,
接受类型为f2
的a->b
。也就是说,它是一个函数,具有某种类型的输入f
(a
可以是任何东西,这里没有限制)和某种类型的返回值a
b
- 然后
获取f2
哪个输入的类型必须匹配g
的输出,因此它是f
。它不能像b->c
(其中e->c
与e
不同),或者代码没有意义,因为它不可能组成b
f。g
- 对于第三个参数,
,类型为h
,情况也完全相同c->d
- 函数合成的结果(f2返回的内容)是一个新函数,它接受f所做的任何事情,并返回h返回的任何事情,因此它是
。通过这个,我们已经涵盖了整个类型定义a->d
基本上,它是一个相对较长的定义,但我认为它的本质非常简单。我同意你的观点,在我的问题中,它与(b->c)等价,但我不明白为什么类型表达式