jfmengels/elm-review-simplify/2.0.0

NOTE: the latest version is 2.1.15

Simplify

Reports when an expression can be simplified.

config =
    [ Simplify.rule Simplify.defaults
    ]

Rule to simplify Elm code.

Configuration for this rule. Create a new one with defaults and use ignoreCaseOfForTypes to alter it.

Default configuration for this rule. Use ignoreCaseOfForTypes if you want to change the configuration.

config =
    [ Simplify.defaults
        |> Simplify.ignoreCaseOfForTypes [ "Module.Name.Type" ]
        |> Simplify.rule
    ]

Ignore some reports about types used in case expressions.

This rule simplifies the following construct:

module Module.Name exposing (..)


type Type = A | B


case value of
    A -> x
    B -> x
--> x

In some cases, you may want to disable this simplification because you expect to change or add constructors to this custom type. Keeping the case expression as it is will make the compiler remind you to update this code when you add new variants, which can be valuable.

Using the following configuration, case of expressions — where all variants of the Type custom type from the Module.Name module appear — will not be simplified.

config =
    [ Simplify.defaults
        |> Simplify.ignoreCaseOfForTypes [ "Module.Name.Type" ]
        |> Simplify.rule
    ]

Note that if you use a wildcard, you will still get the simplification, since in this case the compiler will not remind you anyway.

case value of
    A -> x
    _ -> x
--> x

I personally don't recommend to use this function too much, because this could be a sign of premature abstraction, and because I think that often You Aren't Gonna Need this code.

Only use it for custom types that you think will change soon. When using it, I recommend not keeping it there too long. Come back after a while to see if this exception is still worth having. Maybe add a comment with the date and an explanation next to each exception?

Try it out

You can try this rule out by running the following command:

elm-review --template jfmengels/elm-review-simplify/example --rules Simplify

Simplifications

Below is the list of all kinds of simplifications this rule applies.

Booleans

x || True
--> True


x || False
--> x


x && True
--> x


x && False
--> False


not True
--> False


x == True
--> x


x /= False
--> x


not x == not y
--> x == y


anything == anything
--> True


anything /= anything
--> False


not >> not
--> identity

If expressions

if True then x else y
--> x


if False then x else y
--> y


if condition then x else x
--> x


if condition then True else False
--> condition


if condition then False else True
--> not condition

Case expressions

case condition of
    True -> x
    False -> y
--> if condition then x else y


case condition of
    False -> y
    True -> x
--> if not condition then x else y


case value of
    A _ -> x
    B -> x
--> x

Basics functions

identity x
--> x


f >> identity
--> f


always x y
--> x


f >> always x
--> always x

Lambdas

(\\() -> x) data
--> x


(\\() y -> x) data
--> (\y -> x)


(\\_ y -> x) data
--> (\y -> x)

Operators

(++) a b
--> a ++ b

Numbers

n + 0
--> n


n - 0
--> n


0 - n
--> -n


n * 1
--> n


n * 0
--> 0


n / 1
--> n


-(-n)
--> n


negate >> negate
--> identity

Strings

"a" ++ ""
--> "a"


String.isEmpty ""
--> True


String.isEmpty "a"
--> False


String.concat []
--> ""


String.join str []
--> ""


String.join "" list
--> String.concat list


String.length "abc"
--> 3


String.repeat n ""
--> ""


String.repeat 0 str
--> ""


String.repeat 1 str
--> str


String.words ""
--> []


String.lines ""
--> []

Maybe

Maybe.map identity x
--> x


Maybe.map f Nothing
--> Nothing


Maybe.map f (Just x)
--> Just (f x)


MaybeThen f Nothing
--> Nothing


Maybe.andThen (always Nothing) x
--> Nothing


Maybe.andThen (\a -> Just b) x
--> Maybe.map (\a -> b) x


Maybe.andThen f (Just x)
--> f x


Maybe.withDefault x Nothing
--> x


Maybe.withDefault x (Just y)
--> y

Result

Result.map identity x
--> x.and


Result.map f (Err x)
--> Err x


Result.map f (Ok x)
--> Ok (f x)


Result.andThen f (Err x)
--> Err x


Result.andThen f (Ok x)
--> f x


Result.andThen (\a -> Ok b) x
--> Result.map (\a -> b) x


Result.withDefault x (Err y)
--> x


Result.withDefault x (Ok y)
--> y

Lists

a :: []
--> [ a ]


a :: [ b ]
--> [ a, b ]


[ a ] ++ list
--> a :: list


[] ++ list
--> list


[ a, b ] ++ [ c ]
--> [ a, b, c ]


[ a, b ] ++ [ c ]
--> [ a, b, c ]


List.concat []
--> []


List.concat [ [ a, b ], [ c ] ]
--> [ a, b, c ]


List.concat [ a, [ 1 ], [ 2 ] ]
--> List.concat [ a, [ 1, 2 ] ]


List.concatMap identity x
--> List.concat list


List.concatMap identity
--> List.concat


List.concatMap (\a -> a) list
--> List.concat list


List.concatMap fn [ x ]
--> fn x


List.concatMap (always []) list
--> []


List.map fn [] -- same for List.filter, List.filterMap, ...
--> []


List.map identity list
--> list


List.map identity
--> identity


List.filter (always True) list
--> list


List.filter (\a -> True) list
--> list


List.filter (always False) list
--> []


List.filter (always True)
--> identity


List.filter (always False)
--> always []


List.filterMap Just list
--> list


List.filterMap (\a -> Just a) list
--> list


List.filterMap Just
--> identity


List.filterMap (always Nothing) list
--> []


List.filterMap (always Nothing)
--> (always [])


List.isEmpty []
--> True


List.isEmpty [ a ]
--> False


List.isEmpty (x :: xs)
--> False


List.all fn []
--> True


List.all (always True) list
--> True


List.any fn []
--> True


List.any (always False) list
--> True


List.range 6 3
--> []


List.length [ a ]
--> 1


List.repeat n []
--> []


List.repeat 0 list
--> []


List.partition fn []
--> ( [], [] )


List.partition (always True) list
--> ( list, [] )

Set

Set.map fn Set.empty -- same for Set.filter, Set.remove...
--> Set.empty


Set.map identity list
--> list


Set.map identity
--> identity


Set.isEmpty Set.empty
--> True


Set.member x Set.empty
--> False


Set.fromList []
--> Set.empty


Set.toList Set.empty
--> []


Set.length Set.empty
--> 0


Set.intersect Set.empty set
--> Set.empty


Set.diff Set.empty set
--> Set.empty


Set.diff set Set.empty
--> set


Set.union set Set.empty
--> set


Set.insert x Set.empty
--> Set.singleton x


Set.partition fn Set.empty
--> ( Set.empty, Set.empty )


Set.partition (always True) set
--> ( list, Set.empty )

Dict

Dict.isEmpty Dict.empty
--> True


Dict.fromList []
--> Dict.empty


Dict.toList Dict.empty
--> []


Dict.size Dict.empty
--> 0

Cmd / Sub

All of these also apply for Sub.

Cmd.batch []
--> Cmd.none


Cmd.batch [ a ]
--> a


Cmd.batch [ a, Cmd.none, b ]
--> Cmd.batch [ a, b ]


Cmd.map identity cmd
--> cmd


Cmd.map fn Cmd.none
--> Cmd.none