import Lean
open Lean System
set_option pp.mvars false
From https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/unknown.20identifier.20in.20.60let.20var.20.3A.3D.20if.20let.60
def getOpt: String → Option String
getOpt (str: String
str : String: Type
String) : Option: Type → Type
Option String: Type
String := str: String
str
def getIO: String → IO String
getIO (str: String
str : String: Type
String) : IO: Type → Type
IO String: Type
String := pure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f α
pure str: String
str
def getOptIO: String → IO (Option String)
getOptIO (str: String
str : String: Type
String) : IO: Type → Type
IO (Option: Type → Type
Option String: Type
String) := pure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f α
pure (some: {α : Type} → α → Option α
some str: String
str)
if let return
worksdefworks₁ :works₁: IO StringIOIO: Type → TypeString := do if letString: Typesomesome: {α : Type _} → α → Option αopt :=opt: StringgetOptgetOpt: String → Option String"str" then let"str": Stringret :=ret: String(<-(<- getIO opt): StringgetIOgetIO: String → IO String(<- getIO opt): Stringoptopt: String) return(<- getIO opt): Stringret else returnret: String"none""none": Stringworks₁ -- works "str"works₁: IO String
let var <- if let
also worksdefworks₂ :works₂: IO StringIOIO: Type → TypeString := do letString: Typevar <- if letvar: Stringsomesome: {α : Type _} → α → Option αopt :=opt: StringgetOptgetOpt: String → Option String"str" then let"str": Stringret :=ret: String(<-(<- getIO opt): StringgetIOgetIO: String → IO String(<- getIO opt): Stringoptopt: String)(<- getIO opt): Stringpurepure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f αpure ret: IO Stringret elseret: Stringpurepure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f αpure "none": IO String"none" return"none": Stringvarvar: Stringworks₂ -- works: "str"works₂: IO String
let var := if let
gives unknown identifier
error: unknown identifier 'opt'
in defoops₀ :oops₀: IO StringIOIO: Type → TypeString := do letString: Typevar := if letvar: Stringsomesome: {α : Type _} → α → Option αopt :=opt: StringgetOptgetOpt: String → Option String"str" then let"str": Stringret :=ret: String(<-(<- getIO : StringgetIOgetIO: String → IO String(<- getIO : String) -- unknown identifier 'opt'): Stringret elseret: String"none" return"none": Stringvarvar: String
<-
, misuse :=
<-
, misuse :=
, gives unknown identifier
error: unknown identifier 'ret'
in defoops₁₁ :oops₁₁: IO StringIOIO: Type → TypeString := do letString: Typesomesome: ?_ → IO (Option String)ret :=ret: ?_getOptIOgetOptIO: String → IO (Option String)"str""str": String-- unknown identifier 'ret'
<-
, misuse :=
, gives type mismatch
error: type mismatch some ret has type Option ?_ : Type but is expected to have type IO (Option String) : Type
in defoops₁₂ :oops₁₂: IO StringIOIO: Type → TypeString := do letString: Type:=getOptIOgetOptIO: String → IO (Option String)"str" | pure "none" -- type mismatch: `IO (Option String)` got `Option ?m.2842` pure ret"str": String
<-
worksdef works₁₃: IO String
works₁₃ : IO: Type → Type
IO String: Type
String := do
let some: {α : Type _} → α → Option α
some ret: String
ret <- getOptIO: String → IO (Option String)
getOptIO "str": String
"str" | pure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f α
pure "none": String
"none"
pure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f α
pure ret: String
ret -- works
:=
, misuse <-
, gives type mismatch
error: type mismatch io has type String : Type but is expected to have type IO String : Type
in defoops₂ :oops₂: IO StringIOIO: Type → TypeString := do letString: Typeio <-io: StringgetIOgetIO: String → IO String"str""str": String-- type mismatch: expected `IO String`, got `String`
if let
, expect :=
, misuse <-
-- def oops₃ : IO String := do
-- if let some opt <- getOpt "str" then -- unexpected token '<-'; expected ':=' or '←'
-- let ret := (<- getIO opt)
-- return ret
-- else
-- return "none"
if let
, expect := (<- ... )
:=
gives me type mismatcherror: type mismatch some opt has type Option ?_ : Type but is expected to have type IO (Option String) : Type
in defoops₄₁ :oops₄₁: IO StringIOIO: Type → TypeString := do if letString: Type:=getOptIOgetOptIO: String → IO (Option String)"str" then -- type mismatch: expected `IO (Option String)`, got `Option ?m.3586` let ret <- getIO opt pure ret else pure "none""str": String
<-
gives me unexpected token '<-'; expected ':=' or '←'
-- def oops₄₂ : IO String := do
-- if let some opt <- getOptIO "str" then -- unexpected token '<-'; expected ':=' or '←'
-- let ret <- getIO opt
-- pure ret
-- else
-- pure "none"
:= (<- ... )
worksdef works₄₃: IO String
works₄₃ : IO: Type → Type
IO String: Type
String := do
if let some: {α : Type _} → α → Option α
some opt: String
opt := (<- getOptIO "str"): Option String
(<- getOptIO: String → IO (Option String)
getOptIO(<- getOptIO "str"): Option String
"str": String
"str"(<- getOptIO "str"): Option String
) then
let ret: String
ret <- getIO: String → IO String
getIO opt: String
opt
pure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f α
pure ret: String
ret
else
pure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f α
pure "none": String
"none"
error: application type mismatch pure false argument false has type Bool : Type but is expected to have type Unit : Type
inexample :example: IO UnitIOIO: Type → TypeUnit := do let x ← ifUnit: Typetrue thentrue: Boolpurepure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f αelsepurepure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f α
error: unknown identifier 'x'
inexample :example: Id UnitIdId: Type → TypeUnit := do let mutUnit: Typex ← ifx: Booltrue thentrue: Boolpurepure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f αtrue elsetrue: Boolpurepure: {f : Type → Type} → [self : Pure f] → {α : Type} → α → f αfalse if letfalse: Bool.true :=.true: Boolx thenx: Bool:=falsefalse: Bool