简体   繁体   English

不知道怎么用。 和Haskell中的$运算符

[英]Don't know how to use . and $ operator in Haskell

I am not sure how to implement the . 我不知道如何实施. and the $ operators to simplify the following definitions: $运算符来简化以下定义:

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

I've read that the . 我已经读过了. operator is a functional composition so that the output of one function goes to the input of another, and $ is a substitute for a parenthesis. operator是一个函数式组合,因此一个函数的输出转到另一个函数的输入,而$是括号的替代。

Therefore, I tried changing it to 因此,我尝试将其更改为

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

But I get type errors saying 但我得到类型错误说

could not match '[Char]' with a0 -> [Char]

I am a bit confused on how to use those operators. 我对如何使用这些运算符感到有点困惑。

I do not see a way of using ($) and (.) in this code. 我没有在这段代码中看到使用($)(.)

However, you can simplify your code as this: 但是,您可以将代码简化为:

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

For instance, this: 例如,这个:

[head as] ++ compress (drop 1 as)

is the same as this: 与此相同:

head as : compress (drop 1 as)

And by using pattern matching, it becomes even shorter: 通过使用模式匹配,它变得更短:

x : compress xs

The operators you want to use are commonly use to write a shorter version (with less parentheses) of a function. 您要使用的运算符通常用于编写函数的较短版本(括号较少)。 For instance, your compress function could be written this way: 例如,您的compress函数可以这样编写:

compress :: [Char] -> [Char]
compress = concatMap (\x -> head x : show (length x)) . group

instead of this: 而不是这个:

compress :: [Char] -> [Char]
compress xs = concat $ map (\x -> head x : show (length x)) $ group xs

or even this 甚至这个

compress :: [Char] -> [Char]
compress xs = concatMap (\x -> head x : show (length x)) (group xs)

Here is a simpler example: 这是一个更简单的例子:

capitalizeWords :: String -> String
capitalizeWords string = unwords (map (\(f:rest) -> toUpper f : rest) (words string))

main = putStrLn (capitalizeWords "here you are")

can be rewritten to: 可以改写为:

capitalizeWords :: String -> String
capitalizeWords = unwords . map (\(f:rest) -> toUpper f : rest) . words

main = putStrLn $ capitalizeWords "here you are"

Here are the explanations: 以下是解释:

The ($) can be used in the main function because this operator can be viewed as wrapping in parentheses what is on the right of it. ($)可以在main函数中使用,因为可以将此运算符视为括在括号中的右侧。

For the capitalizeWords function, it can first be simplify to this: 对于capitalizeWords函数,它可以首先简化为:

capitalizeWords string = unwords $ map (\(f:rest) -> toUpper f : rest) (words string)

using the previous explanation. 使用前面的解释。

Again, we can use ($) : 再次,我们可以使用($)

capitalizeWords string = unwords $ map (\(f:rest) -> toUpper f : rest) $ words string

And as the string parameter is on the right of both side of the equality, we can use composition to remove this parameter. 并且由于string参数位于相等的两侧的右侧,我们可以使用组合来删除此参数。 So we get the final capitalizeWords function shown above. 所以我们得到上面显示的最终capitalizeWords功能。

You can learn more about the ($) and (.) operators here . 您可以在此处了解有关($)(.)运算符的更多信息

There are tools that can help you writing point-free functions like hlint and pointfree . 有一些工具可以帮助您编写像hlintpointfree这样的无点函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM