简体   繁体   English

Haskell:可怕的签名

[英]Haskell: scary type signature

I'm struggling to understand this type signature: 我很难理解这种类型的签名:

Prelude Text.Regex.Posix> :t (=~)
(=~)
  :: (Text.Regex.Base.RegexLike.RegexMaker
        Regex CompOption ExecOption source,
      Text.Regex.Base.RegexLike.RegexContext Regex source1 target) =>
     source1 -> source -> target

I reckon they list type classes, source , source1 and target should be instances of, but the semantics look completely arcane (that is, I would not be able to replicate it, even if I understood what it says). 我认为它们列出了类型类, sourcesource1target应该是实例,但是语义看起来完全是神秘的(即,即使我理解它的内容,我也无法复制它)。

There's nothing strange going on here: just some type classes with a lot of arguments. 这里没什么奇怪的:只是一些带有很多参数的类型类。 (The long Text.Regex.Base... module names don't help, either.) (长的Text.Regex.Base...模块名称也没有帮助。)

  • There must be a RegexMaker instance for: Regex , CompOption , ExecOption , and whatever type source is 必须有一个RegexMaker实例: RegexCompOptionExecOption和任何类型的source都是
  • There must be a RegexContext instance for: Regex , whatever type source1 is, and whatever type target is 必须有一个RegexContext实例: Regex ,无论source1是什么类型,以及target是什么类型
  • The (=~) function itself takes a source1 and a source and gives a target (=~)函数本身采用source1source并给出target

Haskell's own (+) operator is a similar shape to (=~) , but its type is hopefully easier to read: Haskell自己的(+)运算符与(=~)形状类似,但希望它的类型更容易阅读:

(+) :: Num a => a -> a -> a

I wrote a fairly thorough description of the Text.Regex typeclasses in another answer . 我在另一个答案中写了一篇关于Text.Regex类型类的相当详尽的描述。

Copying most of that here... 在这里复制大部分内容......


All the Text.Regex.* modules make heavy use of typeclasses, which are there for extensibility and "overloading"-like behavior, but make usage less obvious from just seeing types. 所有Text.Regex.*模块都大量使用类型类,它们具有可扩展性和“重载”类似的行为,但仅仅看到类型就不那么明显了。

Now, you've probably been started off from the basic =~ matcher. 现在,你可能已经从基本=~匹配器开始了。

(=~) ::
  ( RegexMaker Regex CompOption ExecOption source
  , RegexContext Regex source1 target )
  => source1 -> source -> target
(=~~) ::
  ( RegexMaker Regex CompOption ExecOption source
  , RegexContext Regex source1 target, Monad m )
  => source1 -> source -> m target

To use =~ , there must exist an instance of RegexMaker ... for the LHS, and RegexContext ... for the RHS and result. 要使用=~ ,必须存在用于LHS的RegexContext ...和用于RHS和结果的RegexMaker ...的实例。

class RegexOptions regex compOpt execOpt | ...
      | regex -> compOpt execOpt
      , compOpt -> regex execOpt
      , execOpt -> regex compOpt
class RegexOptions regex compOpt execOpt
      => RegexMaker regex compOpt execOpt source
         | regex -> compOpt execOpt
         , compOpt -> regex execOpt
         , execOpt -> regex compOpt
  where
    makeRegex :: source -> regex
    makeRegexOpts :: compOpt -> execOpt -> source -> regex

A valid instance of all these classes (for example, regex=Regex , compOpt=CompOption , execOpt=ExecOption , and source=String ) means it's possible to compile a regex with compOpt,execOpt options from some form source . 所有这些类的有效实例(例如, regex=RegexcompOpt=CompOptionexecOpt=ExecOptionsource=String )意味着可以使用某些表单source compOpt,execOpt选项编译regex (Also, given some regex type, there is exactly one compOpt,execOpt set that goes along with it. Lots of different source types are okay, though.) (另外,给定一些regex类型,只有一个compOpt,execOpt设置与它一起。但是很多不同的source类型都可以。)

class Extract source
class Extract source
      => RegexLike regex source
class RegexLike regex source
      => RegexContext regex source target
  where
    match :: regex -> source -> target
    matchM :: Monad m => regex -> source -> m target

A valid instance of all these classes (for example, regex=Regex , source=String , target=Bool ) means it's possible to match a source and a regex to yield a target . 所有这些类的有效实例(例如, regex=Regexsource=Stringtarget=Bool )意味着可以匹配sourceregex以产生target (Other valid target s given these specific regex and source are Int , MatchResult String , MatchArray , etc.) (给定这些特定regexsource其他有效targetIntMatchResult StringMatchArray等)

Put these together and it's pretty obvious that =~ and =~~ are simply convenience functions 把这些放在一起很明显=~=~~只是简单的功能

source1 =~ source
  = match (makeRegex source) source1
source1 =~~ source
  = matchM (makeRegex source) source1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM