Подтвердить что ты не робот

"= ~" raise "Нет экземпляра для (RegexContext Regex [Char] [String])"

ОС: MacOSX 10.7.1 GHC и Haskell-платформы от brew.

   GHCi, version 7.0.4: http://www.haskell.org/ghc/  :? for help
    Loading package ghc-prim ... linking ... done.
    Loading package integer-gmp ... linking ... done.
    Loading package base ... linking ... done.
    Loading package ffi-1.0 ... linking ... done.
    Prelude> :m +Text.Regex.Posix
    Prelude Text.Regex.Posix> "foo" =~ "o" :: [String]

    <interactive>:1:7:
        No instance for (RegexContext Regex [Char] [String])
          arising from a use of `=~'
        Possible fix:
          add an instance declaration for
          (RegexContext Regex [Char] [String])
        In the expression: "foo" =~ "o" :: [String]
        In an equation for `it': it = "foo" =~ "o" :: [String]
    Prelude Text.Regex.Posix> "foo" =~ "o" :: String
    Loading package array-0.3.0.2 ... linking ... done.
    Loading package bytestring-0.9.1.10 ... linking ... done.
    Loading package containers-0.4.0.0 ... linking ... done.
    Loading package transformers-0.2.2.0 ... linking ... done.
    Loading package mtl-2.0.1.0 ... linking ... done.
    Loading package regex-base-0.93.2 ... linking ... done.
    Loading package regex-posix-0.95.1 ... linking ... done.
    "o"

Я считаю, что библиотеки обновлены. И я думаю, что выход "foo" =~ "o" :: [String] равен ["o", "o"]

Любое предложение будет оценено.

4b9b3361

Ответ 1

ghci> getAllTextMatches ("foo" =~ "o" :: AllTextMatches [] String)
["o", "o"]

Я не использовал регулярные выражения в Haskell много (что я думаю ответ Дэн Бертон более идиоматичен).

Итак, как я понял это, я посмотрел на вашу ошибку типа No instance for (RegexContext Regex [Char] [String]) и выскочил в ghci:

ghci> :t (=~)
(=~)
  :: (RegexMaker Regex CompOption ExecOption source,
      RegexContext Regex source1 target) =>
     source1 -> source -> target

Итак, RegexContext Regex [Char] [String] - это класс, который включает возвращаемый тип "foo" =~ "o" :: [String]. Поэтому я посмотрел, какие экземпляры этого класса существуют, поэтому я мог бы узнать, каково должно быть возвращаемое значение:

ghci> :i RegexContext
class RegexLike
        regex source => RegexContext regex source target where
  match :: regex -> source -> target
  matchM :: Monad m => regex -> source -> m target
        -- Defined in Text.Regex.Base.RegexLike
instance RegexContext Regex String String
  -- Defined in Text.Regex.Posix.String
instance RegexLike a b => RegexContext a b [[b]]
  -- Defined in Text.Regex.Base.Context
...
instance RegexLike a b => RegexContext a b (AllTextMatches [] b)
  -- Defined in Text.Regex.Base.Context
...

Имя AllTextMatches, казалось, указывало, что вы искали, поэтому я проверил это:

ghci> :i AllTextMatches
newtype AllTextMatches f b
  = AllTextMatches {getAllTextMatches :: f b}
        -- Defined in Text.Regex.Base.RegexLike
instance RegexLike a b => RegexContext a b (AllTextMatches [] b)
  -- Defined in Text.Regex.Base.Context

Таким образом, этот тип использовался для извлечения всех совпадений текста, как я подозревал. Все, что мне нужно было сделать, это указать, что я хотел получить возвращаемое значение этого типа.

Обратите также внимание на возможный тип возвращаемого значения [[b]], который, как я полагаю, возвращает список списков, содержащих каждое полное совпадение и все его подматрицы:

ghci> "foo" =~ "o" :: [[String]]
[["o"],["o"]]
ghci> "foo bar baz" =~ "[aeiou](.)" :: [[String]]
[["oo","o"],["ar","r"],["az","z"]]

Итак, возможно, тип, который вы хотели использовать, вместо [String]. Я мог видеть [String] как слегка неоднозначную, когда существовал [[String]] - должен "foo bar baz" =~ "[aeiou](.)" :: [String] быть fst ("foo bar baz" =~ "[aeiou](.)" :: [[String]]) или map fst ("foo bar baz" =~ "[aeiou](.)" :: [[String]]).

Ответ 2

Это также работает

ghci> getAllTextMatches $ "foo" =~ "o" :: [String]
["o","o"]

Ответ 3

Попробуйте следующее:

Prelude Text.Regex.Posix> getAllTextMatches ("foo" =~ "o" :: AllTextMatches [] String)
["o","o"]

Ответ 4

Еще одно возможное решение:

map head $ "foo" =~ "o" :: [String]

Описание

Привязка результата от (=~) до [[String]] приведет к списку совпадений, в которых каждое соответствие представлено списком строк. В каждом списке его head будет полным совпадением, а tail - совпадением для каждого подматрицы:

> "foo goo bar" =~ "(.)o(.)" :: [[String]]
[["foo","f","o"],["goo","g","o"]]

-- Get the second submatch (2) of the first match (0)
> "foo goo bar" =~ "(.)o(.)" !! 0 !! 2 :: String
"o"

-- Get the first submatch (1) of the second match (1)
> "foo goo bar" =~ "(.)o(.)" !! 1 !! 1 :: String
"g"

Короче говоря, map head $ string =~ regexp :: [String] содержит все совпадения regexp в string. map tail $ string =~ regexp :: [[String]] содержат вспомогательные соответствия, указанные в исходном регулярном выражении, заключая в круглые скобки ().