gpt4 book ai didi

parsing - 如何在 Haskell 中与 Data.Text 进行模式匹配?

转载 作者:行者123 更新时间:2023-12-03 15:41:15 24 4
gpt4 key购买 nike

我目前正在用 Haskell 编写解析器。我有以下代码。

{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}

module Main where

import Data.Text

newtype Parser a = Parser { runParser :: Text -> Either Text (Text, a) }

char1 :: Char -> Parser Char
char1 c = Parser $ \case
(x:xs) | x == c -> Right (xs, x)
_ -> Left "Unexpected character"
它无法编译这两个错误。
test.hs:12:6: error:
• Couldn't match expected type ‘Text’ with actual type ‘[Char]’
• In the pattern: x : xs
In a case alternative: (x : xs) | x == c -> Right (xs, x)
In the second argument of ‘($)’, namely
‘\case
(x : xs) | x == c -> Right (xs, x)
_ -> Left "Unexpected character"’
|
12 | (x:xs) | x == c -> Right (xs, x)
| ^^^^

test.hs:12:24: error:
• Couldn't match type ‘[Char]’ with ‘Text’
Expected type: Either Text (Text, Char)
Actual type: Either Text ([Char], Char)
• In the expression: Right (xs, x)
In a case alternative: (x : xs) | x == c -> Right (xs, x)
In the second argument of ‘($)’, namely
‘\case
(x : xs) | x == c -> Right (xs, x)
_ -> Left "Unexpected character"’
|
12 | (x:xs) | x == c -> Right (xs, x)
| ^^^^^^^^^^^^^
我可以通过替换 Text 来修复错误 String 的数据类型但我更喜欢使用 Text数据类型。
有没有办法与 Data.Text 进行模式匹配?在没有先明确地将其转换为字符串的情况下键入?也许有一个 GHC 扩展可以让我这样做?
提前致谢。

最佳答案

对@DanielWagner 的回答进行了改进,您可以结合 View 模式和模式同义词来做到这一点。你需要一个新的构造函数来代替 : ,但它可能看起来像:

{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}

import Data.Text

pattern x :> xs <- (uncons -> Just (x, xs))
pattern Empty <- (uncons -> Nothing)

findInText :: (Char -> Bool) -> Text -> Maybe Char
findInText _ Empty = Nothing
findInText p (x :> xs) | p x = Just x
| otherwise = findInText p xs
这里的想法是模式 x :> xs是模式 uncons -> Just (x, xs) 的同义词这是通过应用 uncons 操作的 View 模式给检查者,并将结果与​​ Just (x, xs) 进行模式匹配人口 xxs为父模式。
根据评论,可能有人担心这种用法最终是否会调用 uncons不止一次。在完全关闭优化 ( -O0 ) 的情况下,生成的核心确实有多个 uncons调用:
-- unoptimized -O0
findInText
= \ ds ds1 ->
case uncons ds1 of {
Nothing -> Nothing;
Just ipv ->
case uncons ds1 of {
Nothing -> ...
通过优化( -O-O2 ),所有内容都被内联,并且由于 Unicode 处理正在进行,生成的核心非常复杂。但是,如果您还定义:
findInText' :: (Char -> Bool) -> Text -> Maybe Char
findInText' p txt = case uncons txt of
Nothing -> Nothing
Just (x, xs) | p x -> Just x
| otherwise -> findInText' p xs
事实证明,GHC 编译 findInText'至:
findInText' = findInText
所以看起来至少在这种情况下,由于 View 模式,GHC 没有做任何额外的工作。

关于parsing - 如何在 Haskell 中与 Data.Text 进行模式匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66161612/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com