1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
module Check.AST.Pattern.AndOr where

import Curry.SpanInfo
import Curry.Span
import Curry.Position
import Curry.Types
import Curry.Ident
import Text.Pretty

import Types

-- if found an apply on an apply, check
checkAndOr :: Expression a -> Int -> CSM ()
checkAndOr e _ =
  case e of
    (Apply
      sI
      (Apply _
        (Variable _ _
          (QualIdent _ _ (Ident _ _ _)))
        (Variable _ _
          (QualIdent _ _
            (Ident _ _ _))))
      _) -> checkAndOr' e
    _    -> return ()

-- if foldl/foldr is used with || or && use predefined functions 'and' and 'or'
checkAndOr' :: Expression a -> CSM ()
checkAndOr' e =
  case getAndOrAsTupel e of
    (sI, "foldr", "||")  -> (report (Message
                                      (getSpan sI)
                                      ( text "superfluous code"
                                      <+> colorizeKey "foldr ||"
                                      )
                                      ( text "instead of"
                                      <+> colorizeKey "foldr || False"
                                      <+> text "write"
                                      <+> colorizeKey "or")))
    (sI, "foldr", "&&")  -> (report (Message
                                      (getSpan sI)
                                      ( text "superfluous code"
                                      <+> colorizeKey "foldr && True"
                                      )
                                      ( text "instead of"
                                      <+> colorizeKey "foldr &&"
                                      <+> text "write"
                                      <+> colorizeKey "and")))
    (sI, "foldl", "||")  -> (report (Message
                                      (getSpan sI)
                                      ( text "superfluous code"
                                      <+> colorizeKey "foldl ||"
                                      )
                                      ( text "instead of"
                                      <+> colorizeKey "foldl || False"
                                      <+> text "write"
                                      <+> colorizeKey "or"
                                      <+> text "(better use of laziness)")))
    (sI, "foldl", "&&")  -> (report (Message
                                      (getSpan sI)
                                      ( text "superfluous code"
                                      <+> colorizeKey "foldr &&"
                                      )
                                      ( text "instead of"
                                      <+> colorizeKey "foldr && True"
                                      <+> text "write"
                                      <+> colorizeKey "and"
                                      <+> text "(better use of laziness)")))
    _                    -> return ()

-- return relevant parts of ast for catching foldr/foldr ||/&&
getAndOrAsTupel :: Expression a -> (SpanInfo, String, String)
getAndOrAsTupel
  (Apply
    sI
    (Apply _
      (Variable _ _
        (QualIdent _ _ (Ident _ func _)))
      (Variable _ _
        (QualIdent _ _
          (Ident _ inf _))))
    _)
  = (sI, func, inf)