我想知道如何使用ToLower
函数(Char -> Char)
将字符串转换为小写。
这是我到目前为止的代码:
let newlist = (\(h:t) -> c (h) ++ newlist (\c -> toLower c)
我不知道怎么做而不使用递归,我不知道如何在lambda表达式中使用
答案 0 :(得分:12)
考虑到你可以通过eta-reduce来明确命名函数接受的变量,这样会更容易使用lambda表达式。例如,您可以使用列表解析:
import Data.Char
lowerString str = [ toLower loweredString | loweredString <- str]
您可以称之为:
ghci> lowerString "Hello"
hello
或者,您可以使用map
:
lowerString = map toLower
如果你坚持使用lambda表达式,它看起来像这样:
import Data.Char
lowerString = \x -> map toLower x
再次,这不是很好。
答案 1 :(得分:2)
With a lambda expression you'd still need to recursively check each character of the string, or you could use map which is still a recursive function that applies the function (a -> b) to every element in the list, for example:
newList [] = []
newList xs = (\(y:ys) -> if x `elem` ['A'..'Z'] then toLower y : newList ys else y : newList ys) xs
With map is actually much simpler due to reasons explained in the first paragraph, check mnoronha's answer as he already gave you the answer, but that's if you're thinking of using map in conjunction with toLower.
This is an example without a lambda expression, which requires you to import 2 functions from Data.Char, recursively check the rest of the string and replace each character with its lower case version.
newList :: String -> String
newList [] = []
newList (x:xs) = if x `elem` ['A'..'Z']
then chr (ord x + 32) : newList xs
else x : newList xs
or with guards
newList :: String -> String
newList [] = []
newList (x:xs)
| x `elem` ['A'..'Z'] = chr (ord x + 32) : newList xs
| otherwise = x : newList xs
答案 2 :(得分:0)
这可能比它的价值更麻烦但你可以使用fix函数递归调用lambda函数。
fix :: (a -> a) -> a
fix f = let x = f x in x
以下代码使用与此页面相同的方法:https://www.vex.net/~trebla/haskell/fix.xhtml从非lambda版本转换为lambda版本到(最终)使用fix来递归调用lambda函数而不引入新变量< / p>
import Data.Char (toLower)
import Control.Monad.Fix (fix)
main :: IO ()
main = do
-- calling non lambda version
let newlist1 s = if null s then [] else toLower (head s) : newlist1 (tail s)
print $ newlist1 "Hello"
-- calling lambda version
let newlist2 = \s -> if null s then [] else toLower (head s) : newlist2 (tail s)
print $ newlist2 "Hello"
-- defining lambda version locally
-- ( at this point the scope of newlist3 is local to the let statement )
print $ (let newlist3 = \s -> if null s then [] else toLower (head s) : newlist3 (tail s) in newlist3 ) "Hello"
-- making function an argument to be called recursively
print $ (let newlist3 = (\v -> \s -> if null s then [] else toLower (head s) : v (tail s)) newlist3 in newlist3 ) "Hello"
-- isolating function to be "fixed".
let f = (\v -> \s -> if null s then [] else toLower (head s) : v (tail s))
print $ (let newlist3 = f newlist3 in newlist3 ) "Hello"
-- using fix = let x = f x in x
print $ (fix f) "Hello"
-- f2 is slightly simpler version of f
let f2 = (\v s -> if null s then [] else toLower (head s) : v (tail s))
print $ (fix f2) "Hello"
-- inlining f2 to get recursive call to lambda
print $ (fix (\v s -> if null s then [] else toLower (head s) : v (tail s))) "Hello"