Haskell: scary type signature

I am trying to understand a signature of this type:

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 believe that they list the types of classes, source , source1 and target should be instances, but the semantics look completely secret (that is, I would not be able to reproduce it, even if I understood what it says).

+4
source share
2 answers

Nothing strange happens here: only certain types of classes with a large number of arguments. (The long names of the Text.Regex.Base... modules do not help either.)

  • There must be a RegexMaker instance for: Regex , CompOption , ExecOption and any type of source
  • There must be a RegexContext instance for: Regex , of any type source1 and any type of target is
  • The function itself (=~) takes source1 and a source and gives target

Haskell's own (+) operator is similar to (=~) , but its type is hopefully easier to read:

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

I wrote a fairly detailed description of Text.Regex text fields in another answer .

Copying most of this here ...


All Text.Regex.* Modules Text.Regex.* heavy use of type classes that exist for extensibility and "overloading" behavior, but make use less obvious from just seeing types.

Now you probably started working with basic =~ .

 (=~) :: ( 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 be an instance of RegexMaker ... for LHS and RegexContext ... for RHS and the result.

 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 the ability to compile the regex options with compOpt,execOpt from some form of source . (In addition, given some regex type, there is exactly one compOpt,execOpt set compOpt,execOpt , that comes with it. However, many different types of source all the same.)

 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 (e.g. regex=Regex , source=String , target=Bool ) means that it can match a source and a regex to get target . (Other valid target given these specific regex and source are Int , MatchResult String , MatchArray , etc.)

Put them together, and it's pretty obvious that =~ and =~~ are just handy functions

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

Source: https://habr.com/ru/post/1303547/


All Articles