Filter 哈斯克尔多功能合成
我试图理解Haskell中的函数组合 根据ZVONFilter 哈斯克尔多功能合成,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,
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
这些实际上是参数化类型。我们可以使类型参数显式化: