Parsec函数'parse'和类'Stream'的类型签名 [英] The type signature of Parsec function 'parse' and the class 'Stream'

查看:131
本文介绍了Parsec函数'parse'和类'Stream'的类型签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在以下类型声明中约束(Stream s Identity t)意味着什么?

  parse ::(Stream s Identity t)
=> Parsec s()a - > SourceName - > s - > ParseError a

什么是 Stream 在类声明之后,它是什么意思。我完全失去了。

  class Monad m =>流s m t | s  - > t其中

当我使用Parsec时,我遇到了类型签名( xxx :: yyy )。我总是跳过签名,将src加载到ghci中,然后将类型签名复制回我的.hs文件。它的工作原理,但我仍然不明白这些签名是什么。






编辑:更多关于点我的问题。

我仍然对类型签名的'上下文'感到困惑:

 (显示a)=> 

表示 a 必须是类的实例显示

 (Stream s Identity t)=> 

这个'context'的含义是什么,因为 t =>






有很多不同的解析器可以运行,所以我编写了一个warp函数来运行任何具有真实文件的解析器。但问题出在这里:



这是我的代码,它不能被加载,我怎么才能使它工作?

  module RunParse where 
import System.IO
import Data.Functor.Identity(Identity)
import Text.Parsec.Prim(Parsec,parse ,Stream)

- 我该写什么runIOParse :: ...
--runIOParse ::(Stream s Identity t,Show a)=> Parsec s()a - >字符串 - > IO()
runIOParse pa filename =
do
inh< - openFile filename ReadMode $ b $ outh< - openFile(filename ++。.parseout)WriteMode
instr< - hGetContents inh
let result = show $ parse pa filename instr
hPutStr outh result
hClose inh
hClose outh


解决方案


约束:(Stream s Identity t)意味着什么?


这意味着输入 s 解析器可以工作(即 [Char] )必须是 Stream 类的实例。在文档中你看到 [Char] 确实是Stream的一个实例,因为任何列表都是。



参数 t 是标记类型,通常是 Char ,并且 s ,表示函数依赖 s - >吨

但是别担心这个Stream类型。它仅用于为任何类似Stream的类型提供统一的接口,例如列表或ByteStrings。


什么是流


流只是一个类型类。它具有 uncons 函数,该函数返回输入的头部和包含在 Maybe 中的元组尾部。通常你不需要这个功能。就我所见,它只在最基本的解析器中需要,如 tokenPrimEx



编辑:


这个'context'的含义是什么,因为t在=>

$ b之后没有显示$ b

查看函数依赖关系。 <= c $ c> t 在'=>'后不会显示,因为它是由 s 决定的。
这意味着你可以在任何 s 中使用 uncons


这是我的代码,它不能被加载,我怎么才能使它工作?



简单:为 Text.Parsec.String 添加一个导入语句,它为定义缺少的实例。流[tok] m tok 。这里的文档可能会更清晰一些,因为它看起来好像这个实例是在 Text.Parsec.Prim 中定义的。



或者导入整个Parsec库( import Text.Parsec ) - 这是我总是这样做的。


What does the constraint (Stream s Identity t) mean in the following type declaration?

parse :: (Stream s Identity t)
  => Parsec s () a -> SourceName -> s -> Either ParseError a

What is Stream in the following class declaration, what does it mean. I'm totally lost.

class Monad m => Stream s m t | s -> t where

When I use Parsec, I get into a jam with the type-signatures (xxx :: yyy) all the time. I always skip the signatures, load the src into ghci, and then copy the type-signature back to my .hs file. It works, but I still don't understand what all these signatures are.


EDIT: more about the point of my question.

I'm still confused about the 'context' of type-signature:

(Show a) =>

means a must be a instance of class Show.

(Stream s Identity t) => 

what's the meaning of this 'context', since t never showed after the =>


I have a lot of different parser to run, so I write a warp function to run any of those parser with real files. but here comes the problem:

Here is my code, It cannot be loaded, how can I make it work?

module RunParse where
import System.IO
import Data.Functor.Identity (Identity)
import Text.Parsec.Prim (Parsec, parse, Stream)

--what should I write "runIOParse :: ..."
--runIOParse :: (Stream s Identity t, Show a) => Parsec s () a -> String -> IO ()
runIOParse pa filename =
  do
    inh <- openFile filename ReadMode
    outh <- openFile (filename ++ ".parseout") WriteMode
    instr <- hGetContents inh
    let result = show $ parse pa filename instr
    hPutStr outh result
    hClose inh
    hClose outh

解决方案

the constraint: (Stream s Identity t) means what?

It means that the input s your parser works on (i.e. [Char]) must be an instance of the Stream class. In the documentation you see that [Char] is indeed an instance of Stream, since any list is.

The parameter t is the token type, which is normally Char and is determinded by s, as states the functional dependency s -> t.

But don't worry too much about this Stream typeclass. It's used only to have a unified interface for any Stream-like type, e.g. lists or ByteStrings.

what is Stream

A Stream is simply a typeclass. It has the uncons function, which returns the head of the input and the tail in a tuple wrapped in Maybe. Normally you won't need this function. As far as I can see, it's only needed in the most basic parsers like tokenPrimEx.

Edit:

what's the meaning of this 'context', since t never showed after the =>

Have a look at functional dependencies. The t never shows after the ´=>´, because it is determiend by s. And it means that you can use uncons on whatever s is.

Here is my code, It cannot be loaded, how can I make it work?

Simple: Add an import statement for Text.Parsec.String, which defines the missing instance for Stream [tok] m tok. The documentation could be a bit clearer here, because it looks as if this instance was defined in Text.Parsec.Prim.

Alternatively import the whole Parsec library (import Text.Parsec) - this is how I always do it.

这篇关于Parsec函数'parse'和类'Stream'的类型签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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