如何在Functor中打印中间结果并在Haskell中打印Applicative [英] how to print intermediate result in Functor and Applicative in Haskell

查看:64
本文介绍了如何在Functor中打印中间结果并在Haskell中打印Applicative的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读Graham Hutton撰写的《 Haskell编程第二书》. https://www.cs.nott.ac.uk/~ pszgmh/pih.html#slides

I am reading the book Programming in Haskell 2nd by Graham Hutton. https://www.cs.nott.ac.uk/~pszgmh/pih.html#slides

关于第13.4章排序解析器",它包含以下功能:

When it comes to chapter 13.4 Sequencing parsers, it contains the following functions:

> parse three "abcdef" 
[((’a’,’c’),"def")] 
> parse three "ab" 
[]

我想了解在幕后评估它们的中间步骤是什么.您可以在此处找到Functor的有效源代码和Parser的Applicative:

I would like to understand what are the intermediate steps to evaluate them behind the scene. You can find the working source code for the Functor and Applicative for the Parser here:

import Control.Applicative
import Data.Char

-- Basic definitions
newtype Parser a =
  P (String -> [(a, String)])
parse (P p) inp = p inp


item :: Parser Char
item = P (\inp -> case inp of
         [] -> []
         (x:xs) -> [(x, xs)])

-- Sequencing parsers
instance Functor Parser
   -- fmap :: (a -> b) -> Parser a -> Parser b
                                               where
  fmap g p =
    P
      (\inp ->
         case parse p inp of
           [] -> []
           [(v, out)] -> [(g v, out)])
--parse  (fmap toUpper item) "abc"

instance Applicative Parser
   -- pure :: a -> Parser a
                            where
  pure v = P (\inp -> [(v, inp)])
   -- <*> :: Parser (a -> b) -> Parser a -> Parser b
  pg <*> px =
    P
      (\inp ->
         case parse pg inp of
           [] -> []
           [(g, out)] -> parse (fmap g px) out)

three :: Parser (Char, Char)
three = pure g <*> item <*> item <*> item
  where
    g x y z = (x, z)

我已经尝试通过以下方式替换Functor和Applicative的定义,但是不知道如何做进一步:

I have attempted it by substituting the definitions from Functor and Applicative in the following way, but dont know how to do it further:


parse three "abc"



three :: Parser (Char,Char) 
three 
= pure g <*> item <*> item <*> item 
=P (\inp -> [(g,inp)]) <*> item <*> item <*> item        (apply pure v)

-----------------------------------------------------------------------------------------------------------
=P (
\inp -> case parse P (\inp -> [(g,inp)]) inp of         (apply pg <*> px)
[] -> [] 
[(g,out)] -> parse (fmap g item) out
)

<*> item <*> item 
-----------------------------------------------------------------------------------------------------------
=P (
\inp -> case (\inp -> [(g,inp)]) inp of             (apply parse (P p) inp = p inp
[] -> [] 
[(g,out)] -> parse (fmap g item) out
)

<*> item <*> item 

-----------------------------------------------------------------------------------------------------------
Here, inp="abc",  (\inp -> [(g,inp)]),  inp = [  (f x y z =(x,z), "abc"   )]  
=P (
parse (
fmap g item
) out
)                               (apply \inp -> [(g,inp)] on inp)

<*> item <*> item 

推荐答案

(这是对基于@Daniel Wagner的建议,我在fmap g p进行扩展:"更新的回应)

(This is in response to the 'Based on the suggestion of @Daniel Wagner, I expand on fmap g p:' update)

最后一次替换正确吗?

Is the last substitution correct?

无法回答,因为之前的步骤不正确.

It's impossible to answer because steps before that are incorrect.

扩展有几个问题,表明您在编写时马虎,这会导致错误.也可能存在概念上的问题.

There are several problems with your expansion, indicating that you're being sloppy when writing, which has led to mistakes. There might also be conceptual problems.

例如,当您将three = P ...内联到parse three "abc"时,没有在P ...上加上括号,导致出现以下一行:

For example, when you inline three = P ... into parse three "abc", you didn't put parentheses around P ..., leading to this line:

parse P (parse (P ...)) <*> item <*> item "abc"

这在语法上很可能是错误的,因为它会像这样被解析

This is most likely syntactically incorrect, as it would be parsed like

(parse P (parse (P ...))) <*> item <*> (item "abc")

虽然您可能是这样想的:

While you likely meant:

parse ((P ...) <*> item <*> item) "abc"

如果您认为是这样,那么我只是为了使事情更容易写而已,然后检查一下:此语法错误还导致您错误地独立于<*> item <*> item "abc"而在parse P (parse (P ...))部分上工作,这很严重错误,并且使大部分事情变得无关紧要.

If you think, well I'm just doing this to make things easier to write, then check this out: This syntax error also led you to erroneously work on the parse P (parse (P ...)) part independently of <*> item <*> item "abc", which a serious mistake and made most of everything following that irrelevant.

这是另一件事:

Here, inp="abc",  (\inp -> [(g,inp)]),  inp = [  (f x y z =(x,z), "abc"   )]

此行完全没有意义.由于您只是在扩展three,所以说inp是什么是无效的.考虑(\x -> x).此处的x仅仅是建立关系,即结果与参数相同,并且不是任何特定值.这就是 bound 变量的意思.

This line makes no sense at all. Since you are just expanding three, It's not valid to say that inp is anything. Consider (\x -> x). The x here is merely to establish the relationship that the result is the same as the argument, and is not any particular value. This is what is meant by it being a bound variable.

(而且我什至不知道您在说什么(\inp -> [(g,inp)]), inp = [ (f x y z =(x,z), "abc" )]时在说什么.也许您可以澄清一下?)

(And I don't even know what you're talking about when you say (\inp -> [(g,inp)]), inp = [ (f x y z =(x,z), "abc" )]. Maybe you can clarify?)

这也意味着以下内容毫无意义

This also means that the following makes no sense

 (\inp -> case parse item inp of [] -> []; [(v, out)] -> [(g v, out)]))<*> item <*> item "abc"
={substitute inp for "abc"}
 case parse item  "abc" of [] -> []; [(v, out)] -> [(g v, out)]<*> item <*> item 

这里有多个问题.首先,第一行有一个额外的封闭括号,这使得您很难理解您的意思.如果我们忽略了这一点,那么在您使用(\inp ->) <*> item ...之前,但是之后您没有在case表达式周围加上括号,从而使<*>.

There are multiple problems here. To begin with, the first line has an extra close paren, which makes it hard to see what you mean. If we ignore that, then before you had (\inp ->) <*> item ..., but afterwards you did not put parens around the case expression, making <*>.

此外,您似乎想在此处进行beta减少. Beta归约始终采用(\v -> E) a的形式,其中lambda直接应用于自变量.您不能随便说'v等于a'并在表达式中跳转.

Also, it seems that you want to do a beta-reduction here. A beta reduction always has the form (\v -> E) a, in which the lambda is directly applied to an argument. You cannot just say randomly that 'v is equal to a' and jump around in expressions.

例如,如果我们有f (\x -> x + 1) 3,将其减少到f 4是否正确?不,因为未将lambda应用于3.

For example, If we have f (\x -> x + 1) 3, is it right to reduce that to f 4? No, because the lambda isn't being applied to 3.

这意味着即使上半部分是正确的,您编写的下半部分也是基于毫无意义的步骤,并且是无关紧要的.

This means that even if the first half is right, the second half of what you wrote is based on a nonsensical step and is irrelevant.

我非常想告诉您如何解决您的减少问题,但是很抱歉,我认为您写的内容现在已经无法修复.如果要获得正确的归约迹线,请更仔细地注意每个步骤的语法和有效性,然后从头开始再次进行所有操作.

I would very much want to tell you how to fix your reduction, but I'm sorry to say that I think what you wrote is beyond repair by now. If you want to have a correct reduction trace, please be more careful with both the syntax and the validity of each step, and do everything again from scratch.

作为帮助,您应该检查几件事以查看是否出错:

As an aid, there are several things you should check to see if things went wrong:

  1. 每个步骤在语法上均应有效.没有未绑定的变量,没有缺少的括号,等等.
  2. 如果原始表达式进行类型检查,则每个步骤也必须进行类型检查并具有相同的类型.

这篇关于如何在Functor中打印中间结果并在Haskell中打印Applicative的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆