. In GHC version 6.10.4: ...">

What is the difference between "err @ (Left _)" and "Left err"

I am trying to use codes from <Real World Haskell>.

In GHC version 6.10.4:

data ParseState = ParseState {
  string :: String
} deriving (Show)

newtype Parse a = Parse {
  runParse :: ParseState -> Either String (a, ParseState)
}

parse :: Parse a -> String -> Either String a
parse parser initState =
  case runParse parser (ParseState initState) of
    Left err          -> Left err
    Right (result, _) -> Right result

Everything went fine until I changed "Left err" to "err @ (Left _)":

--  err@(Left _)      -> err
{-
 -  Occurs check: cannot construct the infinite type:
 -    a = (a, ParseState)
 -  When generalising the type(s) for `parse'
-}

Any ideas?

+3
source share
1 answer

This is subtle. casechecks the type value Either String (a, ParseState), so when you call the template in

err@(Left _) -> err

errhas the same type. However, the return type of the function says that it should be Either String athat does not match the type err Either String (a, ParseState). Looking at the type Left:

Left :: x -> Either x y

When you use Leftthe right side in

Left err -> Left err

y, a (a, ParseState).

, , , .

, Control.Arrow ( (->) ) :

left :: (a -> a') -> Either a b -> Either a' b
right :: (b -> b') -> Either a b -> Either a b'
(+++) :: (a -> a') -> (b -> b') -> Either a b -> Either a' b'

(: , , ). , :

parse parser = right fst . runParse parser . ParseState
+8

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


All Articles