我正在嘗試撰寫一個函式來檢查字串是否是 Haskell 中的回文(不區分大小寫)。為了確保大寫字符不會引起問題,我首先使用toLower( https://hackage.haskell.org/package/text-2.0/docs/Data-Text.html#v:toLower將字串轉換為小寫)。然后我檢查它是否等于同一事物的反轉版本。這是我的代碼:
{-# LANGUAGE OverloadedStrings #-}
import Data.Text (toLower)
isPalindrome :: String -> Bool
isPalindrome xs = toLower xs == toLower $ reverse xs
我意識到toLower使用文本而不是字串,我們需要使用{-# LANGUAGE OverloadedStrings #-}將字串多載為文本。但這不會編譯。
我也在 GHCI 中復制了這個。我首先用來:set -XOverloadedStrings確保多載字串。然后我運行這個:
Prelude Data.Text> toLower $ reverse "sdssSDSS"
<interactive>:92:11: error:
? Couldn't match expected type ‘Data.Text.Internal.Text’
with actual type ‘[Char]’
? In the second argument of ‘($)’, namely ‘reverse "sdssSDSS"’
In the expression: toLower $ reverse "sdssSDSS"
In an equation for ‘it’: it = toLower $ reverse "sdssSDSS"
我不明白為什么這不起作用。如果我首先運行reverse "sdssSDSS"并將結果復制粘貼到toLower其中,則可以正常作業。
uj5u.com熱心網友回復:
我們需要使用
{-# LANGUAGE OverloadedStrings #-}to 多載String到Text
不。可以說應該呼叫該擴展名OverloadedStringLiterals。它只會改變諸如or之類的文字的行為,但不會在and之間進行轉換。通常,自動轉換在 Haskell 中永遠不會發生,所發生的只是您可以擁有多型值,例如具有該擴展名的數字文字或字串文字。"hello""sdssSDSS"StringText
在現代 Haskell 中,可能最好的選擇就是把它全部寫進去Text,根本不引入String:
import qualified Data.Text as Txt
isPalindrome :: Txt.Text -> Bool
isPalindrome xs = Txt.toLower xs == Txt.toLower (Txt.reverse xs)
(請注意,您不能$在那里使用,因為它的優先級低于==)。
但是您根本不需要使用Text,還有單字符版本toLower:
import Data.Char (toLower)
isPalindrome :: String -> Bool
isPalindrome xs = map toLower xs == map toLower (reverse xs)
順便說一句,在這兩種情況下都toLower只能使用一次:
isPalindrome :: String -> Bool
isPalindrome xs = xsLC == reverse xsLC
where xsLC = map toLower xs
uj5u.com熱心網友回復:
leftaroundabout 已經向您解釋了如何解決您的問題,但我還有一點補充。如果您想使用常規的 Char -> Char 函式和 Text 型別,您可以使用 Lens 和未打包的 ISO 輕松完成(這很方便但速度很慢 :))。
{-# LANGUAGE OverloadedStrings #-}
import Control.Lens
import qualified Data.Text as T
useFun1 :: (String -> String) -> T.Text -> T.Text
useFun1 = over unpacked
useFun2 :: (Char -> Char) -> T.Text -> T.Text
useFun2 = over (unpacked . traversed)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/427245.html
標籤:哈斯克尔
