本文介绍了readsPrec和相关函数如何返回[Red]以读取“[Red]”。 :: [颜色]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 这个问题是执行时会发生什么(读取[Red]):: [颜色] 在ghci?下。从 user5402的答案,我知道有一个非常复杂的执行路径读取[Red] :: [Color] ,其中包括 readsPrec 和 readsPrecList 。根据@ user5402的评论, readsPrecList 调用 readsPrec ,所以 readsPrec 返回 [(Red,])] 到 readsPrecList ,然后我们将得到最终结果 [Red] 来自 readsPrecList 。然而,我仍然不明白链接的哪些功能对应于他的 readsPrecList 及其实现细节。解决方案相关定义可在报告中找到,看起来像这样: read ::(Read a)=>字符串 - > 读取s = case [x | (x,t)< - 读取 [x] - >的s,(,) - lex t] x [] - >错误Prelude.read:no parse _ - >错误Prelude.read:ambiguous parse reads ::(Read a)=>读取a reads = readsPrec 0 实例(读取a)=>阅读[a]其中 readsPrec p = readList class读取其中 readsPrec :: Int - > ReadS a readList :: ReadS [a] readList = readParen False(\r - > [pr |([,s)< - lex r, pr< ; - readl s])其中readl s = [([],t)| (],t) [(x:xs,u)| (x,t)(xs,u) readl's = [([],t)| (],t) [(x:xs,v)| (x',v) $ b(x,u) $ b readParen :: Bool - >读取a - >读一个 readParen b g =如果b那么强制其他可选其中可选r = g r ++强制r 强制r = [(x,u)| | ('(,s) - lex r,(x,t)) - 可选的s,(),u) - lex t] 执行 lex 太大了,它使Haskell松懈。 下面的一段长期的等式推理可以追溯到完整的评估。我假设 Read Color 实例的实现是派生的。由于这里的兴趣是列表和非列表之间的联系,我没有在基类型 Color 上扩展和评估 reads 的细节。 c $ c $。 pre $ 读取[Red]:: [([Color],String)] = {读取的定义} readsPrec 0[Red] = {readsPrec @ [Color]的定义} readList[Red] = {readList的定义@Color} readParen False(\r - > [pr |([,s) where readl s = [([],t)| (],t) [(x:xs,u)| (x,t)(xs,u) readl's = [([],t)| (],t) [(x:xs,v)| (x',v) = {b,x,u)定义readParen} (\r - > [pr |([,s) where readl s = [([],t)| (],t) [(x:xs,u)| (x,t)(xs,u) readl's = [([],t)| (],t) [(x:xs,v)| (x',v)强制性r(b,x) = [(x,u)| ((,s)(x,t)(),u) = {beta reduction} [pr | ([,s) - lex[Red],pr 其中{ - 与之前相同 - } = {评估`强制性'[红色]`和`(++)`} [pr | ([,s) - lex[Red],pr 其中{ - 与之前相同 - } = {lex[Red]= ([,Red)]} [pr | pr 其中{ - 与之前相同 - } = {这种缩减的名称,但我不知道} readl Red where { - 与之前相同 - } = {readl的定义} [([],t)| (],t) [(x:xs,u)| (x,t)< - 读出Red],(xs,u)其中 readl's = [([],t) | (],t) [(x:xs,v)| (x',v) = {b,x,u) lexRed]= [(Red,])]加评估(++)} [(x:xs,u)| (x,t)(xs,u)其中{ - 与之前相同 - } = {读取红色]= [(红色,])]} [(红色:xs,u)| (xs,u)< - readl']] 其中{ - 与之前相同 - } = {readl'的定义} [(Red:xs,u)| (xs,u) [(x:xs,v)| (x',v) b其中{ - 与以前相同 - } = {lex]= [(],)]} [(Red:xs,u)| (++)和列表理解} [([Red],)的评估(++) )] 我们可以将此派生用作评估读取的构建块,因为这是您的顶级问题。 读取[Red]:: [Color ] = {读取的定义} 案例[x | (x,t) [x] - >的[Red],(,) [] - >错误Prelude.read:no parse _ - >错误Prelude.read:ambiguous parse = {reads[Red]= [([Red],)]} case [[Red] | (,) [x] - > x [] - >错误Prelude.read:no parse _ - >错误Prelude.read:ambiguous parse = {lex= [(,)]} case [[Red]] of [x] - > x [] - >错误Prelude.read:no parse _ - >错误Prelude.read:ambiguous parse = {同样有一个名称用于缩减情况,但我不知道它} [Red] This question is a continuation of what happens when executing (read "[Red]") :: [Color] under ghci?. From user5402's answer, I know that there is a very complex execution path for read "[Red]" :: [Color] , which includes readsPrec and readsPrecList. According to @user5402's comments, readsPrecList call the readsPrec, so readsPrec returns [(Red,"]")] to readsPrecList and then we will get the final result [Red] from readsPrecList. However, I still cannot understand what function of the link corresponds to his readsPrecList and its implementation details. 解决方案 The relevant definitions are available in the Report, and look like this:read :: (Read a) => String -> aread 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 areads = readsPrec 0instance (Read a) => Read [a] where readsPrec p = readListclass 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 areadParen 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 ]The implementation of lex is much too large to include here -- it lexes Haskell.A longish piece of equational reasoning below traces the full evaluation. I assume the implementation of the Read Color instance is the derived one. Since the interest here is the connection between lists and non-lists, I elide the details of expanding and evaluating reads at the base type Color.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],"")]We can use this derivation as a building block for evaluating read, since that's your top-level question.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] 这篇关于readsPrec和相关函数如何返回[Red]以读取“[Red]”。 :: [颜色]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-21 23:25