singletons-2.4: tests/compile-and-dump/Singletons/LetStatements.hs
{-# OPTIONS_GHC -Wno-unused-binds -Wno-unused-matches
-Wno-name-shadowing -Wno-unused-imports #-}
module Singletons.LetStatements where
import Data.Singletons
import Data.Singletons.Prelude
import Data.Singletons.SuppressUnusedWarnings
import Data.Singletons.TH
import Singletons.Nat
$(singletons [d|
-- type signature required for a constant
foo1 :: Nat -> Nat
foo1 x = let y :: Nat
y = Succ Zero
in y
-- nothing in scope, no type signatures required
foo2 :: Nat
foo2 = let y = Succ Zero
z = Succ y
in z
-- using in-scope variable
foo3 :: Nat -> Nat
foo3 x = let y :: Nat
y = Succ x
in y
-- passing in-scope variable to a function. Tests also adding in-scope binders
-- at the call site of f
foo4 :: Nat -> Nat
foo4 x = let f :: Nat -> Nat
f y = Succ y
in f x
-- nested lets, version 1. This could potentially be problematic.
foo5 :: Nat -> Nat
foo5 x = let f :: Nat -> Nat
f y = let z :: Nat
z = Succ y
in Succ z
in f x
-- nested lets, version 2. This shouldn't cause any problems, so that's just a
-- sanity check.
foo6 :: Nat -> Nat
foo6 x = let f :: Nat -> Nat
f y = Succ y
in let z :: Nat
z = f x
in z
-- name shadowing
foo7 :: Nat -> Nat
foo7 x = let x :: Nat
x = Zero
in x
-- lambda binder in let shadows pattern-bound variable
foo8 :: Nat -> Nat
foo8 x = let z :: Nat
z = (\x -> x) Zero
in z
-- let-declaring lambdas
foo9 :: Nat -> Nat
foo9 x = let z :: Nat -> Nat
z = (\x -> x)
in z x
-- infix declaration
foo10 :: Nat -> Nat
foo10 x = let (+) :: Nat -> Nat -> Nat
Zero + m = m
(Succ n) + m = Succ (n + m)
in (Succ Zero) + x
-- infix call uses let-bound binder
foo11 :: Nat -> Nat
foo11 x = let (+) :: Nat -> Nat -> Nat
Zero + m = m
(Succ n) + m = Succ (n + m)
z :: Nat
z = x
in (Succ Zero) + z
-- infix let-declaration uses in-scope variable
foo12 :: Nat -> Nat
foo12 x = let (+) :: Nat -> Nat -> Nat
Zero + m = m
(Succ n) + m = Succ (n + x)
in x + (Succ (Succ Zero))
-- make sure that calls to functions declared outside of let don't receive
-- extra parameters with in-scope bindings. See #18.
foo13 :: forall a. a -> a
foo13 x = let bar :: a
bar = x
in foo13_ bar
foo13_ :: a -> a
foo13_ y = y
-- tuple patterns in let statements. See #20
foo14 :: Nat -> (Nat, Nat)
foo14 x = let (y, z) = (Succ x, x)
in (z, y)
|])
foo1a :: Proxy (Foo1 Zero)
foo1a = Proxy
foo1b :: Proxy (Succ Zero)
foo1b = foo1a
foo2a :: Proxy Foo2
foo2a = Proxy
foo2b :: Proxy (Succ (Succ Zero))
foo2b = foo2a
foo3a :: Proxy (Foo3 (Succ Zero))
foo3a = Proxy
foo3b :: Proxy (Succ (Succ Zero))
foo3b = foo3a
foo4a :: Proxy (Foo4 (Succ Zero))
foo4a = Proxy
foo4b :: Proxy (Succ (Succ Zero))
foo4b = foo4a
foo5a :: Proxy (Foo5 Zero)
foo5a = Proxy
foo5b :: Proxy (Succ (Succ Zero))
foo5b = foo5a
foo6a :: Proxy (Foo6 Zero)
foo6a = Proxy
foo6b :: Proxy (Succ Zero)
foo6b = foo6a
foo7a :: Proxy (Foo7 (Succ (Succ Zero)))
foo7a = Proxy
foo7b :: Proxy Zero
foo7b = foo7a
foo8a :: Proxy (Foo8 (Succ (Succ Zero)))
foo8a = Proxy
foo8b :: Proxy Zero
foo8b = foo8a
foo9a :: Proxy (Foo9 (Succ (Succ Zero)))
foo9a = Proxy
foo9b :: Proxy (Succ (Succ Zero))
foo9b = foo9a
foo10a :: Proxy (Foo10 (Succ (Succ Zero)))
foo10a = Proxy
foo10b :: Proxy (Succ (Succ (Succ Zero)))
foo10b = foo10a
foo11a :: Proxy (Foo11 (Succ (Succ Zero)))
foo11a = Proxy
foo11b :: Proxy (Succ (Succ (Succ Zero)))
foo11b = foo11a
foo12a :: Proxy (Foo12 (Succ (Succ (Succ Zero))))
foo12a = Proxy
foo12b :: Proxy (Succ (Succ (Succ (Succ (Succ (Succ Zero))))))
foo12b = foo12a
foo13a :: Proxy (Foo13 Zero)
foo13a = Proxy
foo13b :: Proxy Zero
foo13b = foo13a
foo14a :: Proxy (Foo14 Zero)
foo14a = Proxy
foo14b :: Proxy '(Zero, Succ Zero)
foo14b = foo14a