在 Haskell 中的类型转换

3
我需要在Haskell中将字符串转换为整数。我有一个函数,它将句子中的第三个单词作为字符串获取,但是我的所有句子中的第三个单词都是数字(整数),我该如何将字符串转换为整数,以便之后可以使用该数字进行操作,例如加法或乘法?
getThirdWord :: String -> String
getThirdWord = head . tail . tail . words

我正在使用Visual Haskell Studio。 我如何在其中使用像map和zip这样的函数? 我需要包含任何插件才能使它们起作用吗?
非常感谢您提前的帮助!
4个回答

14

Yacoby的回答是正确的。我有两点补充:

  1. read非常通用,它不仅可以将String转换为Int,其返回类型也取决于上下文。在这种情况下,getThirdWord被定义为String -> Int,所以read知道该如何执行。但并非总是这样,如果你在使用read时遇到编译错误,请记住:你可能需要帮助Haskell确定返回类型。
  2. 目前你使用head . tail . tail获取第三个列表元素。但如果你想要第23个元素怎么办?更可维护和易读的解决方案是使用(!!):这样你就可以检索任何索引处的列表元素。因此:

    thirdWordAsInt :: String -> Int 
    thirdWordAsInt = read . (!! 2) . words
    

    请注意索引是从0开始的,因此要用2而不是3。


6

关于类型转换,请查看read函数。

getThirdWord :: String -> Int
getThirdWord = read . head . tail . tail . words

Visual Haskell Studio 似乎只是一个集成开发环境(IDE), 因为后端使用支持Haskell规范并包含包括map和fold在内的库的GHC


3
我同意使用read,但请记住,head/tailread都是部分函数,可能在空列表上失败。如果可以使用模式匹配,最好避免使用head。例如,
get3rd :: String -> String
get3rd s =
  case (take 3 $ words s) of
    [_,_,w]   -> w
    otherwise -> ""

这个函数对于任何输入都是安全的(如果少于3个单词,它只会返回一个空字符串)。当然,如果您绝对确定列表始终非空,可以使用head/tail

使用read,您可以捕获异常(不太方便),或者改用reads

toInt :: String -> Maybe Int
toInt s =
  case reads s of
    [(i,_)]   -> Just i
    otherwise -> Nothing

-- test cases
main = do
  print . toInt . get3rd $ "1 2 3"
  print . toInt . get3rd $ "one two three"
  print . toInt . get3rd $ "short list"

这个toInt函数返回一个数字或者Nothing(如果无法解析)。你也可以使用Safe库和它的readMay函数。


1
你应该补充说明,只要你确定不会处理空列表,使用 lasthead 是完全可以的。 - Rayne

0
你们说得都没错,但我发帖是因为我想分享一个非常优雅且有用的函数,在学习时可以帮助处理文本的读取和显示。
as :: (Read a, Show a) => (a -> a) -> String -> String
as f = show . f . read

Prelude> as (+1) "7"
"8"

Prelude> as (+(1/2)) "5"
"5.5"

有用,是吧? = P。此外,xs !! n获取xs的第n个元素。查看其他答案以了解打印的简单方法。

为什么不将 (Read a, Show b) => (a -> b) -> String -> String 作为类型呢? - sepp2k
懂了。你的方法很有道理,我想我只是为了简单起见这样做了。 - codebliss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接