-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add documentation for GHC-38520 (Redundant Bang Patterns)
Fixes #177
- Loading branch information
Showing
10 changed files
with
156 additions
and
0 deletions.
There are no files selected for viewing
5 changes: 5 additions & 0 deletions
5
message-index/messages/GHC-38520/alreadyDeconstructed/after/AlreadyDeconstructed.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module AlreadyDeconstructed where | ||
|
||
doubleIfTrue :: (Int, Bool) -> Int | ||
doubleIfTrue (x, y) | y = x * 2 | ||
doubleIfTrue x = fst x |
5 changes: 5 additions & 0 deletions
5
message-index/messages/GHC-38520/alreadyDeconstructed/before/AlreadyDeconstructed.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module AlreadyDeconstructed where | ||
|
||
doubleIfTrue :: (Int, Bool) -> Int | ||
doubleIfTrue (x, y) | y = x * 2 | ||
doubleIfTrue !x = fst x |
21 changes: 21 additions & 0 deletions
21
message-index/messages/GHC-38520/alreadyDeconstructed/index.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
--- | ||
title: Already deconstructed | ||
--- | ||
|
||
## Warning message | ||
|
||
``` | ||
AlreadyDeconstructed.hs:5:15: warning: [-Wredundant-bang-patterns] | ||
Pattern match has redundant bang | ||
In an equation for ‘doubleIfTrue’: doubleIfTrue x = ... | ||
| | ||
5 | doubleIfTrue !x = fst x | ||
| ^ | ||
``` | ||
|
||
## Explanation | ||
|
||
It is possible that a previous match clause already forced the evaluation of a value, | ||
just to reject it and try later patterns. | ||
For example, `doubleIfTrue`'s first clause already deconstructs the pair tuple, so | ||
a bang pattern on the tuple as a whole has no effect in the second clause. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
--- | ||
title: Redundant Bang Patterns | ||
summary: Used a Bang Pattern that has no Effect | ||
severity: warning | ||
flag: -Wredundant-bang-patterns | ||
introduced: 9.6.1 | ||
--- | ||
|
||
The `BangPatterns` extension allows the user to mark (parts of) a pattern match as strict, | ||
compared to Haskell's default of only evaluating a pattern match as little as it needs to | ||
to determine whether to reject it or not. | ||
This is done by prefixing the pattern with an exclamation mark, `!`. | ||
Using bang patterns causes such values to always be strictly evaluated to Weak head normal | ||
form (WHNF), before the rest of the matches, any guard patterns or the right-hand side | ||
of a function clause are executed. | ||
|
||
However, there are cases where a bang pattern can be redundant. | ||
Either this is because a previous match clause was already stricter, because the user is | ||
trying to match on a strict field of a data type, or because the type of the value being | ||
matched on is of an unlifted or unboxed type like `Int#` or `Array#`. | ||
|
||
In all of these cases, the Bang Pattern has no added effect, so it is redundant. |
6 changes: 6 additions & 0 deletions
6
message-index/messages/GHC-38520/strictField/after/StrictField.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module StrictField where | ||
|
||
data Foo = MkFoo !Int Int | ||
|
||
foo :: Foo -> Foo -> () | ||
foo !a (MkFoo b !c) = () |
6 changes: 6 additions & 0 deletions
6
message-index/messages/GHC-38520/strictField/before/StrictField.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module StrictField where | ||
|
||
data Foo = MkFoo !Int Int | ||
|
||
foo :: Foo -> Foo -> () | ||
foo !a (MkFoo !b !c) = () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
--- | ||
title: Strict fields | ||
--- | ||
|
||
## Warning message | ||
|
||
``` | ||
UnliftedTypes.hs:17:6: warning: [-Wredundant-bang-patterns] | ||
Pattern match has redundant bang | ||
In an equation for ‘foo’: foo a = ... | ||
| | ||
17 | foo !a !b !c = () | ||
| ^ | ||
``` | ||
|
||
## Explanation | ||
|
||
Haskell allows a user to annotate fields of a datatype as strict, by prepending | ||
their type with an exclamation mark `!`. | ||
Pattern matching on such a constructor forces it to WHNF, but this also automatically | ||
forces any strict fields to evaluate to WHNF as well. | ||
Thus, a Bang Pattern has no effect on a strict field. |
17 changes: 17 additions & 0 deletions
17
message-index/messages/GHC-38520/unliftedTypes/after/UnliftedTypes.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{-# LANGUAGE BangPatterns #-} | ||
{-# LANGUAGE DataKinds #-} | ||
{-# LANGUAGE MagicHash #-} | ||
{-# LANGUAGE GADTs #-} | ||
{-# LANGUAGE KindSignatures #-} | ||
{-# LANGUAGE UnboxedTuples #-} | ||
{-# LANGUAGE UnliftedNewtypes #-} | ||
|
||
module UnliftedTypes where | ||
|
||
import GHC.Exts | ||
|
||
newtype MyInt :: TYPE 'IntRep where | ||
MkMyInt :: Int# -> MyInt | ||
|
||
foo :: Int# -> MyInt -> (# Int, Int #) -> () | ||
foo a b c = () |
17 changes: 17 additions & 0 deletions
17
message-index/messages/GHC-38520/unliftedTypes/before/UnliftedTypes.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{-# LANGUAGE BangPatterns #-} | ||
{-# LANGUAGE DataKinds #-} | ||
{-# LANGUAGE MagicHash #-} | ||
{-# LANGUAGE GADTs #-} | ||
{-# LANGUAGE KindSignatures #-} | ||
{-# LANGUAGE UnboxedTuples #-} | ||
{-# LANGUAGE UnliftedNewtypes #-} | ||
|
||
module UnliftedTypes where | ||
|
||
import GHC.Exts | ||
|
||
newtype MyInt :: TYPE 'IntRep where | ||
MkMyInt :: Int# -> MyInt | ||
|
||
foo :: Int# -> MyInt -> (# Int, Int #) -> () | ||
foo !a !b !c = () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
--- | ||
title: Unlifted and Unboxed Types | ||
--- | ||
|
||
## Warning messages | ||
|
||
``` | ||
UnliftedTypes.hs:17:6: warning: [-Wredundant-bang-patterns] | ||
Pattern match has redundant bang | ||
In an equation for ‘foo’: foo a = ... | ||
| | ||
17 | foo !a !b !c = () | ||
| ^ | ||
UnliftedTypes.hs:17:9: warning: [-Wredundant-bang-patterns] | ||
Pattern match has redundant bang | ||
In an equation for ‘foo’: foo b = ... | ||
| | ||
17 | foo !a !b !c = () | ||
| ^ | ||
UnliftedTypes.hs:17:12: warning: [-Wredundant-bang-patterns] | ||
Pattern match has redundant bang | ||
In an equation for ‘foo’: foo c = ... | ||
| | ||
17 | foo !a !b !c = () | ||
| ^ | ||
``` | ||
|
||
## Explanation | ||
|
||
Forcing the evaluation of a value up to WHNF breaks down with unlifted and | ||
unboxed types, which explicitly lack a wrapping thunk (there is no *box*), | ||
and so values of such types are already always strict. | ||
Thus, trying to enforce strictness via a bang pattern has no effect. |