2016-10-20 103 views
2

我想知道如何使用ToLower函数(Char -> Char)将字符串转换为小写字母。如何使用lambda表达式将字符串转换为小写

这是我的代码至今:

let newlist = (\(h:t) -> c (h) ++ newlist (\c -> toLower c) 

我看不出如何做到这一点不使用递归,我不知道如何在lambda表达式使用

+1

'let lowercase = map toLower'。然后,将其称为“小写”Hello“'。 – Alec

回答

6

考虑到你可以通过eta-reduce来不明确地命名你的函数接受的变量,不使用lambda表达式会更容易。例如,你可以使用一个使用列表理解:

import Data.Char 

lowerString str = [ toLower loweredString | loweredString <- str] 

,你会打电话为:

ghci> lowerString "Hello" 
hello 

或者,你可以使用map

lowerString = map toLower 

如果你坚持使用拉姆达表达式,它看起来像这样:

import Data.Char 

lowerString = \x -> map toLower x 

再次,这不是很好。

2

随着你仍然需要递归查询字符串的每个字符,或者你可以使用这仍然是适用的功能递归函数lambda表达式(A - > B)每个元素在列表中,例如:

newList [] = [] 
    newList xs = (\(y:ys) -> if x `elem` ['A'..'Z'] then toLower y : newList ys else y : newList ys) xs 

随着地图其实要简单得多,由于原因的第一个段落解释,检查mnoronha的回答,因为他已经给了你答案,但是这是如果你想的与toLower结合使用地图。

这是一个没有lambda表达式的例子,它需要你从Data.Char中导入2个函数,递归地检查其余的字符串并用小写字母替换每个字符。

newList :: String -> String 
newList [] = [] 
newList (x:xs) = if x `elem` ['A'..'Z'] 
       then chr (ord x + 32) : newList xs 
       else x : newList xs 

或警卫

newList :: String -> String 
newList [] = [] 
newList (x:xs) 
    | x `elem` ['A'..'Z'] = chr (ord x + 32) : newList xs 
    | otherwise = x : newList xs 
+1

你测试了你的代码吗?它看起来像一旦到达字符串的末尾就会失败,因为你从不指定如何处理空尾'[]'。 – chi

+0

应该现在就可以了,我总是在处理列表时忘记了,谢谢 – Bargros

+0

's == []'将永远是错误的,因为's = x:xs'因此它不是空的。 – chi

0

这可能是更多的麻烦比它的价值,但你可以使用修复功能来递归调用lambda函数。

fix :: (a -> a) -> a 
fix f = let x = f x in x 

下面的代码使用这个页面上所用的相同方法:https://www.vex.net/~trebla/haskell/fix.xhtml从非 - 拉姆达版本而不引入新的变量

过渡到的λ版本(最终)使用修复可递归调用lambda函数
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" 
相关问题