我不确定如何实现.
和$
运算符来简化以下定义:
compress :: [Char] -> [Char]
compress [] = []
compress as
| g as 1 == 1 = [head as] ++ compress (drop 1 as)
| otherwise = [head as] ++ show (g as 1) ++ compress (drop (g as 1) as)
g :: [Char] -> Int -> Int
g [] i = i
g (a:[]) i = i
g (a:as) i
| a == head as = g as (i + 1)
| otherwise = i
main = getLine >>= str -> putStrLn $ compress str
我读过.
运算符是一个函数组合,因此一个函数的输出转到另一个函数的输入,而$
是括号的替代品。
因此,我尝试将其更改为
compress :: [Char] -> [Char]
compress [] = []
compress as
| g as 1 == 1 = [head as] ++ compress . drop 1 as
| otherwise = [head as] ++ show (g as 1) ++ compress . drop (g as 1) as
g :: [Char] -> Int -> Int
g [] i = i
g (a:[]) i = i
g (a:as) i
| a == head as = g as (i + 1)
| otherwise = i
main = getLine >>= str -> putStrLn $ compress str
但是我收到键入错误说
could not match '[Char]' with a0 -> [Char]
我对如何使用这些运算符有点困惑。
我没有看到在此代码中使用($)
和(.)
的方法。
但是,您可以按如下方式简化代码:
compress :: [Char] -> [Char]
compress [] = []
compress as@(x:xs)
| g as 1 == 1 = x : compress xs
| otherwise = x : show (g as 1) ++ compress (drop (g as 1) as)
g :: [Char] -> Int -> Int
g (a:as) i
| a == head as = g as (i + 1)
| otherwise = i
g _ i = i
main = getLine >>= putStrLn . compress
例如,这个:
[head as] ++ compress (drop 1 as)
同这个:
head as : compress (drop 1 as)
通过使用模式匹配,它变得更短:
x : compress xs
要使用的运算符通常用于编写函数的较短版本(括号较少)。例如,您的compress
函数可以这样编写:
compress :: [Char] -> [Char]
compress = concatMap (x -> head x : show (length x)) . group
取而代之的是:
compress :: [Char] -> [Char]
compress xs = concat $ map (x -> head x : show (length x)) $ group xs
甚至这个
compress :: [Char] -> [Char]
compress xs = concatMap (x -> head x : show (length x)) (group xs)
下面是一个更简单的示例:
capitalizeWords :: String -> String
capitalizeWords string = unwords (map ((f:rest) -> toUpper f : rest) (words string))
main = putStrLn (capitalizeWords "here you are")
可以重写为:
capitalizeWords :: String -> String
capitalizeWords = unwords . map ((f:rest) -> toUpper f : rest) . words
main = putStrLn $ capitalizeWords "here you are"
以下是解释:
($)
可以在main
函数中使用,因为可以将此运算符视为将其右侧的内容括在括号中。
对于capitalizeWords
函数,可以先简化为:
capitalizeWords string = unwords $ map ((f:rest) -> toUpper f : rest) (words string)
使用前面的解释。
同样,我们可以使用($)
:
capitalizeWords string = unwords $ map ((f:rest) -> toUpper f : rest) $ words string
由于 string
参数位于相等式两侧的右侧,因此我们可以使用组合来删除此参数。所以我们得到了上面显示的最终capitalizeWords
函数。
您可以在此处了解有关($)
和(.)
运算符的更多信息。
有一些工具可以帮助您编写无点函数,如 hlint 和 pointfree。