所以我不太确定如何正确地表达这句话,但是说我想获取列表中所有奇数的和,我是否有两个函数(sumList和getOddNumbers)并将它们组合成sumOddList或是否存在一种将这两个功能整合在一起的方法?如果没有更好的功能,我如何将它们精确地组合成sumOddList?
getOddNumbers :: [Integer] -> [Integer]
getOddNumbers [] = []
getOddNumbers (x:xs)
|odd x = x:getOddNumbers xs
|otherwise = getOddNumbers xs
sumList :: [Integer] -> Integer
sumList list = case list of
[] -> 0
(x:xs) -> x + (sumList xs)
我还问主要是因为在使用CodeWorld输出颜色和形状时,将两个diff函数放在一起是我以前遇到的难题。
谢谢
(注意:我已经使用Haskell超过5周了,显然我是一个菜鸟)
答案 0 :(得分:5)
您基本上想做的是使用将getOddNumbers
的输出用作{{1}的 input }函数,因此我们可以将sumList
函数定义为:
sumOddList
这里sumOddList :: [Integer] -> Integer
sumOddList l = sumList (getOddNumbers l)
是我们要处理的列表,因此结果是l
结果上的函数应用程序(带有getOddNumbers l
函数)。
sumList
功能上面的模式很常见:我们经常想先通过函数(.)
传递数据,然后通过函数g
传递结果。 Haskell具有(.) :: (b -> c) -> (a -> b) -> a -> c
函数以“链接”函数。因此,我们可以将f
和sumList
链接在一起,就像:
getOddNumbers
请注意,我们在这里不再使用sumOddList :: [Integer] -> Integer
sumOddList = (.) sumList getOddNumbers
参数。 l
在这里定义为“管道”,其中数据首先传递到sumOddList
,然后由getOddNumbers
函数进行“后处理”。
sumList
函数也可以用作中缀运算符:
(.)
答案 1 :(得分:3)
以下是三种等效的编写函数Options +SymLinksIfOwnerMatch -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine On
#If your website is installed in a subfolder, change the line below to reflect the path to the subfolder.
#e.g. for http://www.example.com/subdomain1/subdomain2/ make it RewriteBase /subdomain1/subdomain2
RewriteBase /
#If you wish to use a custom 404 page, place a file named 404.php in your website's root and uncomment the line below.
#If your website is installed in a subfolder, change the line below to reflect the path to the subfolder.
#e.g. for http://www.example.com/subdomain1/subdomain2/ make it ErrorDocument 404 /subdomain1/subdomain2/404.php
#ErrorDocument 404 /404.php
#If your site begins with 'www', uncomment the following two lines
#RewriteCond %{HTTP_HOST} !^www\.
#RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteRule ^(.*)\.htm$ $1.html [R=permanent]
#DO NOT EDIT BELOW THIS
RewriteRule ^index.php$ $1.html [R=301,L,QSA]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule . - [L]
#slots.php
RewriteRule ^slots$ "$0/" [R=301,L,QSA]
RewriteRule ^slots/$ slots.php [L,QSA]
RewriteRule ^slots/.*?([^\.\/]*)\.html$ slots.php?pname=$1 [L,QSA]
RewriteRule ^slots/([1-2]\d{3})/(?:(0[1-9]|1[0-2])/(?:(0[1-9]|1[0-9]|2[0-9]|3[0-1])/)?)?$ slots.php?d=$1$2$3 [L,QSA]
RewriteRule ^slots/[^\.]*?([^/\.]*)/$ slots.php?fname=$1 [L,QSA]
RewriteRule ^slots/[^\.]*?([^/\.]*)$ "$0/" [R=301,L,QSA]
#root.php
RewriteRule ^root$ "$0/" [R=301,L,QSA]
RewriteRule ^root/$ root.php [L,QSA]
RewriteRule ^root/.*?([^\.\/]*)\.html$ root.php?pname=$1 [L,QSA]
RewriteRule ^root/([1-2]\d{3})/(?:(0[1-9]|1[0-2])/(?:(0[1-9]|1[0-9]|2[0-9]|3[0-1])/)?)?$ root.php?d=$1$2$3 [L,QSA]
RewriteRule ^root/[^\.]*?([^/\.]*)/$ root.php?fname=$1 [L,QSA]
RewriteRule ^root/[^\.]*?([^/\.]*)$ "$0/" [R=301,L,QSA]
#news.php
RewriteRule ^news$ "$0/" [R=301,L,QSA]
RewriteRule ^news/$ news.php [L,QSA]
RewriteRule ^news/.*?([^\.\/]*)\.html$ news.php?pname=$1 [L,QSA]
RewriteRule ^news/([1-2]\d{3})/(?:(0[1-9]|1[0-2])/(?:(0[1-9]|1[0-9]|2[0-9]|3[0-1])/)?)?$ news.php?d=$1$2$3 [L,QSA]
RewriteRule ^news/[^\.]*?([^/\.]*)/$ news.php?fname=$1 [L,QSA]
RewriteRule ^news/[^\.]*?([^/\.]*)$ "$0/" [R=301,L,QSA]
#globals.php
RewriteRule ^globals$ "$0/" [R=301,L,QSA]
RewriteRule ^globals/$ globals.php [L,QSA]
RewriteRule ^globals/.*?([^\.\/]*)\.html$ globals.php?pname=$1 [L,QSA]
RewriteRule ^globals/([1-2]\d{3})/(?:(0[1-9]|1[0-2])/(?:(0[1-9]|1[0-9]|2[0-9]|3[0-1])/)?)?$ globals.php?d=$1$2$3 [L,QSA]
RewriteRule ^globals/[^\.]*?([^/\.]*)/$ globals.php?fname=$1 [L,QSA]
RewriteRule ^globals/[^\.]*?([^/\.]*)$ "$0/" [R=301,L,QSA]
#freeplaygame.php
RewriteRule ^freeplaygame$ "$0/" [R=301,L,QSA]
RewriteRule ^freeplaygame/$ freeplaygame.php [L,QSA]
RewriteRule ^freeplaygame/.*?([^\.\/]*)\.html$ freeplaygame.php?pname=$1 [L,QSA]
RewriteRule ^freeplaygame/([1-2]\d{3})/(?:(0[1-9]|1[0-2])/(?:(0[1-9]|1[0-9]|2[0-9]|3[0-1])/)?)?$ freeplaygame.php?d=$1$2$3 [L,QSA]
RewriteRule ^freeplaygame/[^\.]*?([^/\.]*)/$ freeplaygame.php?fname=$1 [L,QSA]
RewriteRule ^freeplaygame/[^\.]*?([^/\.]*)$ "$0/" [R=301,L,QSA]
#download.php
RewriteRule ^download$ "$0/" [R=301,L,QSA]
RewriteRule ^download/$ download.php [L,QSA]
RewriteRule ^download/.*?([^\.\/]*)\.html$ download.php?pname=$1 [L,QSA]
RewriteRule ^download/([1-2]\d{3})/(?:(0[1-9]|1[0-2])/(?:(0[1-9]|1[0-9]|2[0-9]|3[0-1])/)?)?$ download.php?d=$1$2$3 [L,QSA]
RewriteRule ^download/[^\.]*?([^/\.]*)/$ download.php?fname=$1 [L,QSA]
RewriteRule ^download/[^\.]*?([^/\.]*)$ "$0/" [R=301,L,QSA]
#casino.php
RewriteRule ^casino$ "$0/" [R=301,L,QSA]
RewriteRule ^casino/$ casino.php [L,QSA]
RewriteRule ^casino/.*?([^\.\/]*)\.html$ casino.php?pname=$1 [L,QSA]
RewriteRule ^casino/([1-2]\d{3})/(?:(0[1-9]|1[0-2])/(?:(0[1-9]|1[0-9]|2[0-9]|3[0-1])/)?)?$ casino.php?d=$1$2$3 [L,QSA]
RewriteRule ^casino/[^\.]*?([^/\.]*)/$ casino.php?fname=$1 [L,QSA]
RewriteRule ^casino/[^\.]*?([^/\.]*)$ "$0/" [R=301,L,QSA]
#articles.php
RewriteRule ^articles$ "$0/" [R=301,L,QSA]
RewriteRule ^articles/$ articles.php [L,QSA]
RewriteRule ^articles/.*?([^\.\/]*)\.html$ articles.php?pname=$1 [L,QSA]
RewriteRule ^articles/([1-2]\d{3})/(?:(0[1-9]|1[0-2])/(?:(0[1-9]|1[0-9]|2[0-9]|3[0-1])/)?)?$ articles.php?d=$1$2$3 [L,QSA]
RewriteRule ^articles/[^\.]*?([^/\.]*)/$ articles.php?fname=$1 [L,QSA]
RewriteRule ^articles/[^\.]*?([^/\.]*)$ "$0/" [R=301,L,QSA]
#index.php
RewriteRule ^.*?([^\.\/]*)\.html$ ?pname=$1 [L,QSA]
RewriteRule ^([1-2]\d{3})/(?:(0[1-9]|1[0-2])/(?:(0[1-9]|1[0-9]|2[0-9]|3[0-1])/)?)?$ ?d=$1$2$3 [L,QSA]
RewriteRule ^[^\.]*?([^/\.]*)/$ ?fname=$1 [L,QSA]
RewriteRule ^\w[^\.]*?([^/\.]*)$ "$0/" [R=301,L,QSA]
</IfModule>
的方法:
oddSum :: [Integer] -> Integer
顺便说一句,看看Prelude中的oddSum xs = sumList (getOddNumbers xs)
oddSum xs = sumList $ getOddNumbers xs
oddSum = sumList . getOddNumbers
和filter
函数,您可以分别用它们替换sum
和getOddNumbers
。
答案 2 :(得分:1)
还是有办法将这两个功能整合到一个函数中……
sumOddList
?
是的。
通过将一个人的输出用作另一个人的输入来进行连锁功能,尤其是在延迟评估的情况下,但是让我们依赖于要由编译器执行的 fusion 。毕竟,不能保证会发生(通常不会)。
相反,你说的是什么:
mapping f cons x xs = cons (f x) xs
filtering p cons x xs = if (p x) then (cons x xs) else xs
transduce xf cons z xs = foldr (xf cons) z xs
sumOddList xs = transduce (filtering odd) (+) 0 xs
因此
> sumOddList [1..10]
25
> sum [1,3..10]
25
> transduce (mapping (+1) . filtering odd) (+) 0 [1..10]
35
> sum . filter odd . map (+1) $ [1..10]
35
> sum . map (+1) . filter odd $ [1..10]
30
> transduce (filtering odd . mapping (+1)) (+) 0 [1..10]
30
之所以有用,是因为折叠是通过组成其减速器函数的变换器(如上面的mapping
和filtering
来变换其减速器参数cons
)来实现的:
foldr (+) 0
. foldr (\x r -> x+1 : r) []
. foldr (\x r -> if odd x then x : r else r) []
$ [1..10]
=
foldr (+) 0
. foldr ((\cons x r -> cons (x+1) r) (:)) []
. foldr ((\cons x r -> if odd x then cons x r else r) (:)) []
$ [1..10]
=
foldr ((\cons x r -> cons (x+1) r) (+)) 0
. foldr ((\cons x r -> if odd x then cons x r else r) (:)) []
$ [1..10]
=
foldr ((\cons x r -> if odd x then cons x r else r)
((\cons x r -> cons (x+1) r) (+))) 0
$ [1..10]
=
foldr ( ( (\cons x r -> if odd x then cons x r else r)
. (\cons x r -> cons (x+1) r) ) (+)) 0
$ [1..10]
=
foldr ( (filtering odd . mapping (+1)) (+)) 0
$ [1..10]
=
foldr ( filtering odd ( mapping (+1) (+))) 0
$ [1..10]
=
30
一个foldr
在做三个的工作。通过在cons
操作中抽象出化简器函数,从而组成明确地实现了融合,每个这样变化的函数变成了cons
转换器,因此很容易成为 >与其他类似的cons
转换函数组成。