首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >readsPrec和相关函数如何返回[Red]表示"[Red]“::[Color]

readsPrec和相关函数如何返回[Red]表示"[Red]“::[Color]
EN

Stack Overflow用户
提问于 2014-12-14 00:09:45
回答 1查看 275关注 0票数 0

这个问题是在ghci下?的延续。从用户5402的答案中,我知道read "[Red]" :: [Color]有一个非常复杂的执行路径,其中包括readsPrecreadsPrecList。根据@ then 5402的注释,readsPrecList调用readsPrec,因此readsPrec[(Red,"]")]返回给readsPrecList,然后我们将从readsPrecList获得最终结果[Red]。但是,我仍然无法理解链接的哪些功能与他的readsPrecList及其实现细节相对应。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-14 01:18:26

相关的定义可以在报告中获得,如下所示:

代码语言:javascript
复制
read             :: (Read a) => String -> a
read s           =  case [x | (x,t) <- reads s, ("","") <- lex t] of
                         [x] -> x
                         []  -> error "Prelude.read: no parse"
                         _   -> error "Prelude.read: ambiguous parse"

reads            :: (Read a) => ReadS a
reads            =  readsPrec 0

instance  (Read a) => Read [a]  where
    readsPrec p      = readList

class  Read a  where
    readsPrec        :: Int -> ReadS a
    readList         :: ReadS [a]
    readList         = readParen False (\r -> [pr | ("[",s)  <- lex r,
                                                    pr       <- readl s])
                       where readl  s = [([],t)   | ("]",t)  <- lex s] ++
                                        [(x:xs,u) | (x,t)    <- reads s,
                                                    (xs,u)   <- readl' t]
                             readl' s = [([],t)   | ("]",t)  <- lex s] ++
                                        [(x:xs,v) | (",",t)  <- lex s,
                                                    (x,u)    <- reads t,
                                                    (xs,v)   <- readl' u]

readParen        :: Bool -> ReadS a -> ReadS a
readParen b g    =  if b then mandatory else optional
                    where optional r  = g r ++ mandatory r
                          mandatory r = [(x,u) | ("(",s) <- lex r,
                                                 (x,t)   <- optional s,
                                                 (")",u) <- lex t    ]

lex的实现太大了,不可能包含在这里--它将Haskell列出来。

下面的一段长时间的等式推理追踪到了完整的评估。我假设Read Color实例的实现是派生的。因为这里感兴趣的是列表和非列表之间的关联,所以我详细介绍了在基本类型reads中展开和计算Color的细节。

代码语言:javascript
复制
reads "[Red]" :: [([Color], String)]
= { definition of reads }
readsPrec 0 "[Red]"
= { definition of readsPrec @[Color] }
readList "[Red]"
= { definition of readList @Color }
readParen False (\r -> [pr | ("[",s)  <- lex r, pr <- readl s]) "[Red]"
    where readl  s = [([],t)   | ("]",t)  <- lex s] ++
                     [(x:xs,u) | (x,t)    <- reads s,
                                 (xs,u)   <- readl' t]
          readl' s = [([],t)   | ("]",t)  <- lex s] ++
                     [(x:xs,v) | (",",t)  <- lex s,
                                 (x,u)    <- reads t, 
                                 (xs,v)   <- readl' u]
= { definition of readParen }
(\r -> [pr | ("[",s) <- lex r, pr <- readl s] ++ mandatory r) "[Red]"
    where readl  s = [([],t)   | ("]",t)  <- lex s] ++
                     [(x:xs,u) | (x,t)    <- reads s,
                                 (xs,u)   <- readl' t]
          readl' s = [([],t)   | ("]",t)  <- lex s] ++
                     [(x:xs,v) | (",",t)  <- lex s,
                                 (x,u)    <- reads t, 
                                 (xs,v)   <- readl' u]
          mandatory r = [(x,u) | ("(",s) <- lex r,
                                 (x,t)   <- optional s,
                                 (")",u) <- lex t]
= { beta reduction }
[pr | ("[",s) <- lex "[Red]", pr <- readl s] ++ mandatory "[Red]"
    where {- same as before -}
= { evaluation of `mandatory "[Red]"` and `(++)` }
[pr | ("[",s) <- lex "[Red]", pr <- readl s]
    where {- same as before -}
= { lex "[Red]" = [("[", "Red]")] }
[pr | pr <- readl "Red]"]
    where {- same as before -}
= { there's a name for this kind of reduction, but I don't know it }
readl "Red]"
    where {- same as before -}
= { definition of readl }
[([],t)   | ("]",t)  <- lex "Red]"] ++
[(x:xs,u) | (x,t)    <- reads "Red]",
            (xs,u)   <- readl' t]
where
          readl' s = [([],t)   | ("]",t)  <- lex s] ++
                     [(x:xs,v) | (",",t)  <- lex s,
                                 (x,u)    <- reads t, 
                                 (xs,v)   <- readl' u]
= { lex "Red]" = [("Red", "]")] plus evaluation of (++) }
[(x:xs,u) | (x,t)    <- reads "Red]",
            (xs,u)   <- readl' t]
where {- same as before -}
= { reads "Red]" = [(Red, "]")] }
[(Red:xs,u) | (xs,u) <- readl' "]"]
where {- same as before -}
= { definition of readl' }
[(Red:xs,u) | (xs,u) <- [([],t)   | ("]",t)  <- lex "]"] ++
                        [(x:xs,v) | (",",t)  <- lex "]",
                                    (x,u)    <- reads t, 
                                    (xs,v)   <- readl' u]]
where {- same as before -}
= { lex "]" = [("]", "")] }
[(Red:xs,u) | (xs,u) <- [([],"")] ++ []]
= { evaluation of (++) and the list comprehension }
[([Red],"")]

我们可以使用这个派生作为评估read的构建块,因为这是您的顶级问题。

代码语言:javascript
复制
read "[Red]" :: [Color]
= { definition of read }
case [x | (x,t) <- reads "[Red]", ("","") <- lex t] of
    [x] -> x
    []  -> error "Prelude.read: no parse"
    _   -> error "Prelude.read: ambiguous parse"
= { reads "[Red]" = [([Red], "")] }
case [[Red] | ("","") <- lex ""] of
    [x] -> x
    []  -> error "Prelude.read: no parse"
    _   -> error "Prelude.read: ambiguous parse"
= { lex "" = [("", "")] }
case [[Red]] of
    [x] -> x
    []  -> error "Prelude.read: no parse"
    _   -> error "Prelude.read: ambiguous parse"
= { again there's a name for case reduction but I don't know it }
[Red]
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27465001

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档