【问题标题】:Convert a String list to an Int list将 String 列表转换为 Int 列表
【发布时间】:2009-05-28 09:16:05
【问题描述】:

我有一个字符串列表,是否可以将其转换为整数列表?
例如:

["1","2"] -> [1,2]

【问题讨论】:

    标签: haskell functional-programming casting


    【解决方案1】:

    f :: [String] -> [Int]
    f = map read
    

    没有?

    【讨论】:

      【解决方案2】:

      这失败了:

      map read ["1","2"]
      [*Exception: Prelude.read: no parse
      

      方法是:

       map (read::String->Int) ["1","2"]
       [1,2]
       :: [Int]
      

      在 GHCI 之外,在 .hs 文件中它会是:

      let intList = map (read::String->Int) ["1","2"]
      

      【讨论】:

      • 我知道我这次谈话有点晚了,但也可以这样做:map read ["1", "2"] :: [Int]
      【解决方案3】:

      此类问题的一般答案是将任务拆分为多个部分:[String] -> [Int] 看起来像是 String -> Int[a] -> [b] 的组合。 Hoogle(链接)会给你一些结果,让我们看看......

      $ hoogle 'String -> Int'
      Test.HUnit.Base 标签 :: 字符串 -> 节点
      前奏错误 :: [Char] -> a
      前奏长度 :: [a] -> Int
      Data.List 长度 :: [a] -> Int
      Data.Char digitToInt :: Char -> Int
      Data.Char ord :: Char -> Int
      Debug.Trace 跟踪 :: String -> a -> a
      Network.BufferType buf_fromStr :: BufferOp a -> String -> a
      Network.Socket 发送 :: Socket -> String -> IO Int
      Graphics.UI.GLUT.Callbacks.Window Char :: Char -> Key
      Prelude read :: Read a => String -> a
      Text.Read read :: Read a => String -> a
      Data.String fromString :: IsString a => String -> a
      GHC.Exts fromString :: IsString a => String -> a
      Control.Monad.Trans.Error strMsg :: Error a => String -> a
      Control.Monad.Error.Class strMsg :: Error a => String -> a
      ...

      呃,很多垃圾。我们可以先把那些和你无关的包去掉……

      前奏错误 :: [Char] -> a
      前奏长度 :: [a] -> Int
      Data.List 长度 :: [a] -> Int
      Data.Char digitToInt :: Char -> Int
      Data.Char ord :: Char -> Int
      Prelude read :: Read a => String -> a
      Text.Read read :: Read a => String -> a
      Data.String fromString :: IsString a => String -> a
      Text.Printf printf :: PrintfType r => String -> r

      error 听起来不像你想要的。 length 也不是。 digitToInt?听起来有点对——而且实际上是有效的,但只是使用个位数的数字。 read?也许不是您所期望的名称,但如果您仔细想想,这是正确的:将字符串转换为更有意义的内容(如数字)就像阅读一些文本。

      好吧,另一方面,Hoogle 给了我们我们想要的东西:

      $ hoogle '[a] -> [b]'
      前奏图 :: (a -> b) -> [a] -> [b]
      Data.List 映射 :: (a -> b) -> [a] -> [b]
      前奏 concatMap :: (a -> [b]) -> [a] -> [b]
      Data.List concatMap :: (a -> [b]) -> [a] -> [b]
      Data.Maybe mapMaybe :: (a -> Maybe b) -> [a] -> [b]
      前奏循环 :: [a] -> [a]
      Data.List 循环 :: [a] -> [a]
      前奏初始化 :: [a] -> [a]
      Data.List init :: [a] -> [a]
      前奏反转 :: [a] -> [a]

      如您所见,这些函数中的大多数都被称为“map”,这可能又不是您所期望的名称——但显然这就是该操作的名称!你要找的那个是最简单的。

      最后,我们需要结合这两个功能。 map 需要另一个函数作为它的第一个参数——好吧,那显然是 read!因此,您只需将map 应用于read。下一个参数是[a]s 的列表:啊哈,我们已经完成了!

      您可以通过启动 ghci 来检查:

      前奏曲> :t 地图阅读
      地图读取 :: 读取 b => [字符串] -> [b]

      这里还有b 而不是Int,但别介意:b 可以是任何你想要的类型! – 只要它有一个Read 实例。 Int 有:

      前奏曲> :i Int
      data Int = GHC.Types.I# GHC.Prim.Int# -- 定义在 `GHC.Types'
      instance Bounded Int -- 定义在 `GHC.Enum'
      instance Enum Int -- 定义在 `GHC.Enum'
      instance Eq Int -- 在“GHC.Classes”中定义
      instance Integral Int -- 在 `GHC.Real' 中定义
      instance Num Int -- 定义在 `GHC.Num'
      instance Ord Int -- 定义在 `GHC.Classes'
      instance Read Int -- 定义在 `GHC.Read'
      instance Real Int -- 在 `GHC.Real' 中定义
      实例 Show Int -- 在 `GHC.Show' 中定义

      【讨论】:

        猜你喜欢
        • 2020-03-12
        • 2011-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-25
        相关资源
        最近更新 更多