Filter 哈斯克尔多功能合成

Filter 哈斯克尔多功能合成,filter,composition,Filter,Composition,我试图理解Haskell中的函数组合 根据ZVON filter函数应该有两个参数,一个bool函数和一个list 示例过滤器(>5)[1,2,3,4,5,6,7,8]返回大于5的任何值: [6,7,8] 问题,下面的几行函数组合如何传入布尔值以供过滤器使用 映射fst。过滤snd。阿索克斯。soeA 不应该是地图fst吗。过滤器(=真)snd。阿索克斯。soeA 要进行分析,我运行组合的前两个函数并传递一个参数:assocs。soeA$9返回 [(0,错误),(1,错误),(2,正确),(3,

我试图理解Haskell中的函数组合

根据ZVON
filter函数应该有两个参数,一个bool函数和一个list

示例
过滤器(>5)[1,2,3,4,5,6,7,8]
返回大于5的任何值:
[6,7,8]

问题,下面的几行函数组合如何传入布尔值以供过滤器使用

映射fst。过滤snd。阿索克斯。soeA

不应该是地图fst吗。过滤器(=真)snd。阿索克斯。soeA

要进行分析,我运行组合的前两个函数并传递一个参数:
assocs。soeA$9
返回

[(0,错误),(1,错误),(2,正确),(3,正确),(4,错误),(5,正确),(6,错误),(7,正确),(8,错误),(9,错误)]

soe 9
返回
[2,3,5,7]

不知何故,soeA的每个数组元素中的bool值都被使用了,但是任何解释此组合如何工作的帮助都将非常感谢

完整代码为: `

module FastSeive在哪里
进口管制
进口管制站
导入Data.Array.ST
导入Data.Array.unbox
soeST::对于所有s。Int->ST s(STU阵列Int布尔)
soeST n=do
arr writeArray arr i False)[0,1]
设n2=n`div`2
让循环::Int->ST s()
循环i | i>n2=返回()
循环i=do
b ST s()
重置j | j>n=返回()
重置j=写入阵列arr j False>>重置(j+i)
当b(复位(2*i))时
循环(成功i)
环路2
返回arr
soeA::Int->UArray Int Bool
soeA n=runST(soeST n>>=freeze)
soe::Int->[Int]
soe=映射fst。过滤snd。阿索克斯。soeA
soeCount::Int->Int
soeCount=长度。过滤器id。元素。soeA

`简单的回答是:这里,
snd
Bool
-返回函数
过滤器
所期望的。在您编写的表达式中:
map fst。过滤器(=真)snd。阿索克斯。soeA
snd
将是
filter
的第二个参数,而
(==True)
将是第一个参数。当然,它不会进行类型检查,因为
filter
已经应用于两个参数,并且不能用于函数组合:它不再是函数了


要获得更长的答案,我们可以实际应用
(.)
的定义来了解发生了什么:

(f . g) x = f (g x)
-- In haskell, it is defined as being right associative

-- Meaning that if we put explicit parenthesises, we'd have:
soe = (map fst . (filter snd . (assocs . soeA)))
-- That only really matters for the compiler, though,
-- because we know function composition is associative.

soe = map fst . filter snd . assocs . soeA
-- "Un-pointfree-ing" it:
soe x = (map fst . filter snd . assocs . soeA) x
-- Applying (.)'s definition:
soe x = map fst ((filter snd . assocs . soeA) x)
-- Again:
soe x = map fst (filter snd ((assocs . soeA) x))
-- And again:
soe x = map fst (filter snd (asocs (soeA x)))
现在很清楚,
snd
filter
的第一个参数,而第二个参数的计算结果是
assocs(soeax)
的计算结果

更一般地说,当一个人写
f时。Gh
,它可以从右向左读取,作为一个函数,首先对其参数应用
h
,然后对结果应用
g
,然后对下一个结果应用
f
,并生成最终值


现在,对于更长的答案,我们可以看看如何推断表达式的类型。它将告诉我们为什么
snd
Bool
返回函数
filter
所期望的,即使它的类型签名为
snd::(a,b)->b

免责声明:我没有编译工程背景;我将使用的术语可能不准确

过滤器的类型是
(a->Bool)->[a]->[a]
snd
的类型是
(a,b)->b

这些实际上是参数化类型。我们可以使类型参数显式化:

filter :: forall a.   (a -> Bool) -> [a] -> [a]
snd    :: forall a b. (a, b) -> b
我们还将重命名
filter
的类型参数,以使其在下一篇文章中不含糊:

filter :: forall c. (c -> Bool) -> [c] -> [c]
filter
首先应用于
snd
。因此,我们可以尝试将
c->Bool
filter
(a,b)->b
snd
的类型统一起来。我们得到这些方程:

c -> Bool = (a, b) -> b

===

c = (a, b)
b = Bool

===

c = (a, Bool)
b = Bool
我们假设
assocs(soeax)
的类型是
[(Int,Bool)]
。由于
filter
的第二个参数的类型为
[c]
,因此我们可以进一步统一:

[c] = [(Int, Bool)]

===

c = (Int, Bool)
这也给了我们:

(Int, Bool) = c = (a, Bool)

===

a = Int
因此,在类型应用之后,我们得到子表达式的以下具体类型:

filter :: ((Int, Bool) -> Bool) -> [(Int, Bool)] -> [(Int, Bool)]
snd    ::  (Int, Bool) -> Bool

当然,我们可以一直使用GHC的类型推断来告诉我们,或者使用GHCi,或者通过文本编辑器的haskell插件。

简短的回答是:
snd
Bool
-返回函数
过滤器
期望。在您编写的表达式中:
map fst。过滤器(=真)snd。阿索克斯。soeA
snd
将是
filter
的第二个参数,而
(==True)
将是第一个参数。当然,它不会进行类型检查,因为
filter
已经应用于两个参数,并且不能用于函数组合:它不再是函数了


要获得更长的答案,我们可以实际应用
(.)
的定义来了解发生了什么:

(f . g) x = f (g x)
-- In haskell, it is defined as being right associative

-- Meaning that if we put explicit parenthesises, we'd have:
soe = (map fst . (filter snd . (assocs . soeA)))
-- That only really matters for the compiler, though,
-- because we know function composition is associative.

soe = map fst . filter snd . assocs . soeA
-- "Un-pointfree-ing" it:
soe x = (map fst . filter snd . assocs . soeA) x
-- Applying (.)'s definition:
soe x = map fst ((filter snd . assocs . soeA) x)
-- Again:
soe x = map fst (filter snd ((assocs . soeA) x))
-- And again:
soe x = map fst (filter snd (asocs (soeA x)))
现在很清楚,
snd
filter
的第一个参数,而第二个参数的计算结果是
assocs(soeax)
的计算结果

更一般地说,当一个人写
f时。Gh
,它可以从右向左读取,作为一个函数,首先对其参数应用
h
,然后对结果应用
g
,然后对下一个结果应用
f
,并生成最终值


现在,对于更长的答案,我们可以看看如何推断表达式的类型。它将告诉我们为什么
snd
Bool
返回函数
filter
所期望的,即使它的类型签名为
snd::(a,b)->b

免责声明:我没有编译工程背景;我将使用的术语可能不准确

过滤器的类型是
(a->Bool)->[a]->[a]
snd
的类型是
(a,b)->b

这些实际上是参数化类型。我们可以使类型参数显式化: