Case comprehensions
One could argue that the notation <-
is misleading, suggesting the idea of drawn from as in a list comprehension. But it is very nice to reuse precisely the list comprehension syntax.
Pattern guards and Transformational Patterns, Martin Erwig and Simon Peyton Jones.
Reusing just that part of the list-comprehension syntax seems to work for multi-part function definitions:
clunky env var1 var2 | Just val1 <- lookup env var1,
Just val2 <- lookup env var2 = val1 + val2
| otherwise = var1 + var2
but when it's used in case expressions:
-- ghc-8.6.5/compiler/ghci/RtClosureInspect.hs, lines 1099-1107
check2 (_, rtti_ty) (_, old_ty)
| Just (_, rttis) <- tcSplitTyConApp_maybe rtti_ty
= case () of
_ | Just (_,olds) <- tcSplitTyConApp_maybe old_ty
-> and$ zipWith check2 (map quantifyType rttis) (map quantifyType olds)
_ | Just _ <- splitAppTy_maybe old_ty
-> isMonomorphicOnNonPhantomArgs rtti_ty
_ -> True
| otherwise = True
it looks somewhat out-of-place, unless:
map f xs = [ x <- xs -> f x ]
is considered a suitable replacement for:
map f xs = [ f x | x <- xs ]
Could the GHC example benefit from some more list-comprehension syntax? Let's borrow a new reserved word:
check2 (_, rtti_ty) (_, old_ty)
| Just (_, rttis) <- tcSplitTyConApp_maybe rtti_ty
= cases
and $ zipWith check2 (map quantifyType rttis) (map quantifyType olds) |
Just (_,olds) <- tcSplitTyConApp_maybe old_ty
isMonomorphicOnNonPhantomArgs rtti_ty |
Just _ <- splitAppTy_maybe old_ty
True | otherwise
| otherwise = True
...well, at least the unit-case workaround is gone. With a little refactoring:
check2 (_, rtti_ty) (_, old_ty)
| Just (_, rttis) <- tcSplitTyConApp_maybe rtti_ty
= case () of
_ | Just (_,olds) <- tcSplitTyConApp_maybe old_ty
-> and $ zipWith qcheck2 rttis olds
_ | Just _ <- splitAppTy_maybe old_ty
-> isMonomorphicOnNonPhantomArgs rtti_ty
_ -> True
| otherwise = True
qcheck2 rtti old = check2 (quantifyType rtti) (quantifyType old)
and the alternate syntax:
check2 (_, rtti_ty) (_, old_ty)
| Just (_, rttis) <- tcSplitTyConApp_maybe rtti_ty
= cases
and $ zipWith qcheck2 rttis olds | Just (_,olds) <- tcSplitTyConApp_maybe old_ty
isMonomorphicOnNonPhantomArgs rtti_ty | Just _ <- splitAppTy_maybe old_ty
True | otherwise
| otherwise = True
qcheck2 rtti old = check2 (quantifyType rtti) (quantifyType old)
this particular example is further improved, unless:
filter p xs = [ x <- xs, p x -> x ]
is considered a reasonable substitute for:
filter p xs = [ x | x <- xs, p x ]
Still not convinced? Here's some other examples:
|
|
|
|
Atravers 01:37, 10 July 2020 (UTC)