了解 Haskell 类型签名
Understanding Haskell Type Signature
我必须将 Haskell 类型的签名转换为术语。
类型签名是:
f :: (a -> b -> c) -> (d -> b) -> (d -> a) -> d -> c
正确的结果是:
f g h j x = g (j x) (h x)
我的问题就在这里 g
是一个函数 returns 一个函数 returns c
和 c
returns 函数 d
其中 returns b
和 b
是一个函数 returns 本身然后 returns 本身又然后returns c
.
如果我错了请纠正我。
我不明白为什么 g
将 (j x)
作为第一个参数,将 (h x)
作为第二个参数。不应该反过来吗? Haskell 是右结合的,h
是赋予函数 f
而不是 j
.
的第二个参数
g :: a -> b -> c
、h :: d -> b
、j :: d -> a
、x :: d
都是f
的独立参数;它们的顺序与我们最终如何在 f
.
的定义中使用它们无关
首先,我们知道 f
将其参数用于 return 类型 c
的值。但是 none 个参数的值类型为 c
;获取类型 c
的值的唯一方法是使用 g
。但是为了使用 g
,您需要类型为 a
和类型 b
的参数,并且 f
的参数中的 none 具有这些类型。但是我们可以使用 h
和 j
来获取它们,如果我们有一个 d
类型的参数来应用它们,你瞧,我们 do 有一个 d
类型的值:参数 x
!.
f g h j x = let aValue = j x
bValue = h x
cValue = g aValue bValue
in cValue
可以展开为
的原答案
f g h j x = g (j x) (h x)
如果您想将 f
的 return 值视为 d -> c
,而不仅仅是 c
,您可以从中删除 x
带有一些无意义的技巧的定义。
f g h j = g <$> j <*> h -- liftA2 g j h
你甚至可以更进一步,将h
和j
作为参数去掉,但结果虽然简单,却更加难以理解:
f = flip . liftA2
故事的寓意:有时 point-free 样式会抽象掉分散注意力的细节,有时它会完全模糊函数的含义。
我必须将 Haskell 类型的签名转换为术语。 类型签名是:
f :: (a -> b -> c) -> (d -> b) -> (d -> a) -> d -> c
正确的结果是:
f g h j x = g (j x) (h x)
我的问题就在这里 g
是一个函数 returns 一个函数 returns c
和 c
returns 函数 d
其中 returns b
和 b
是一个函数 returns 本身然后 returns 本身又然后returns c
.
如果我错了请纠正我。
我不明白为什么 g
将 (j x)
作为第一个参数,将 (h x)
作为第二个参数。不应该反过来吗? Haskell 是右结合的,h
是赋予函数 f
而不是 j
.
g :: a -> b -> c
、h :: d -> b
、j :: d -> a
、x :: d
都是f
的独立参数;它们的顺序与我们最终如何在 f
.
首先,我们知道 f
将其参数用于 return 类型 c
的值。但是 none 个参数的值类型为 c
;获取类型 c
的值的唯一方法是使用 g
。但是为了使用 g
,您需要类型为 a
和类型 b
的参数,并且 f
的参数中的 none 具有这些类型。但是我们可以使用 h
和 j
来获取它们,如果我们有一个 d
类型的参数来应用它们,你瞧,我们 do 有一个 d
类型的值:参数 x
!.
f g h j x = let aValue = j x
bValue = h x
cValue = g aValue bValue
in cValue
可以展开为
的原答案f g h j x = g (j x) (h x)
如果您想将 f
的 return 值视为 d -> c
,而不仅仅是 c
,您可以从中删除 x
带有一些无意义的技巧的定义。
f g h j = g <$> j <*> h -- liftA2 g j h
你甚至可以更进一步,将h
和j
作为参数去掉,但结果虽然简单,却更加难以理解:
f = flip . liftA2
故事的寓意:有时 point-free 样式会抽象掉分散注意力的细节,有时它会完全模糊函数的含义。