【问题标题】:Convert quoted list to plain list in Haskell在 Haskell 中将引用列表转换为普通列表
【发布时间】:2014-05-29 23:44:32
【问题描述】:

我知道如何使用readString 更改为Int,例如使用

 map read ["3","2","1"] :: [[Int]]

但是当涉及到不规则列表时,我被卡住了,比如

["3","[3,5]","[5,3]"],["4","[1,9]","[2,3]"]

如何将其转换为[[3,[3,5],[5,3]],[4,[1,9],[2,3]]

【问题讨论】:

  • 记住,Haskell 中的每个值都有一个类型。你想要的结果是什么类型的?仔细考虑一下。
  • 我认为应该是 [Int,[Int],[Int]] 但我不知道该用代码表达谁
  • @user3689497 这不是 Haskell 中的有效类型。你可以有类似(Int, [Int], [Int])的东西,但列表必须包含单一类型的元素。
  • 哦,那是真的!谢谢;)

标签: string list haskell


【解决方案1】:

在 Haskell 中无法实现您想要做的事情,因为值 [[3, [3, 5], [5, 4]], [4, [1, 9], [2, 3]] 的类型无效。那里甚至没有足够的右括号,你少了一个。 [3, [3, 5]] 的类型是什么? [[Int]]? [Int]?都不合适。

即使你的例子是错误的:

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

因为[3, 2, 1] 的类型为[Int],而不是[[Int]]。请记住,这不是 Python,列表只能包含单一类型的元素。


相反,如果您有类似["3", "[3,5]", "[5,3]"] 的输入,您可以使用类似的内容对其进行解析

import Text.Read (readMaybe)

readEither :: (Read a, Read b) => String -> Maybe (Either a b)
readEither s = case readMaybe s of
    Just x -> Just $ Left x
    Nothing -> case readMaybe s of
        Just y -> Just $ Right y
        Nothing -> Nothing

这可以更短地表达,但我认为这很好地表达了这一点。然后您可以使用它来解析您的值:

parseMyList :: [String] -> [Maybe (Either Int [Int])]
parseMyList = map readEither

并将其用作

> parseMyList ["3", "[3,5]", "[5,3"]  -- Incomplete last element!
[Just (Left 3), Just (Right [3,5]), Nothing]

我在那里留下了一个意外的错字,所以你可以看到它也优雅地失败了。


可以使用Monoid编写更短的实现:

import Text.Read (readMaybe)
import Data.Monoid

readEither :: (Read a, Read b) => String -> Maybe (Either a b)
readEither = getFirst $ mconcat $ map First [fmap Left $ readMaybe s, fmap Right $ readMaybe s]

也许有人可以打更多的高尔夫球。

【讨论】:

  • 对打高尔夫球不感兴趣,但Either Int [Int] 在这种情况下是一个奇怪的值类型。一棵树几乎肯定是正确的。
  • @luqui 不一定,OP 从未表示这是一个嵌套结构。如果它是一个嵌套结构,那么一棵树肯定是要走的路,但如果它只是在单个 int 或它们的列表之间进行选择,那么一棵树就太过分了。
  • 没错,从技术上讲,是的。我是基于我对许多问题的“平滑性”的期望进行概括的(在这种情况下当然是不知情的)
【解决方案2】:

像 bheklilr 那样使用 readMaybe,我想你可能会使用 [[Int]] 作为结果数据类型。

> import Text.Read (readMaybe)
> map (\x->maybe [read x] id $ readMaybe x) ["3", "[3,5]", "[5,3]"] :: [[Int]]
[[3],[3,5],[5,3]]

如果你想要一个平面列表,你甚至可以在结果上使用concat

【讨论】:

    猜你喜欢
    • 2022-11-21
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多