Zulip Chat Archive
Stream: lean4
Topic: How to prove inhabited and nonempty for partial function def
Sterea Stefan Octavian (Aug 25 2023 at 12:57):
I'm trying to write the Haskell forever
function in Lean, defined in Haskell as:
forever :: (Applicative f) => f a -> f b
forever a = let a' = a *> a' in a'
this function doesn't generally terminate and so can only be a partial function in Lean. However, the docs are not very explicit about how to prove the type implemented by such a function is inhabited and nonempty. I tried
partial def forever {α β} [Applicative f] [Inhabited β] (a : f α) : f β :=
let rec a' : f β := a *> a'; a'
thinking that, since the function is meant to not terminate but take whatever applicative type, that type should be inhabited, right? How to make this work?
Eric Wieser (Aug 25 2023 at 13:02):
This seems like a bad error message:
failed to compile partial definition 'forever.a'', failed to show that type is inhabited and non empty
It would be good if it actually showed the type in question in the message.
Eric Wieser (Aug 25 2023 at 13:04):
This works:
/-- Not safe as a global instance, conflicts with `(default : List Nat) = []` elsewhere -/
def Pure.toInhabited [Pure f] [Inhabited α] : Inhabited (f α) where
default := pure default
attribute [instance] Pure.toInhabited in
partial def forever {α β} [Applicative f] [Inhabited β] (a : f α) : f β :=
a *> forever a
Gabriel Ebner (Aug 25 2023 at 16:22):
-- Safe-ish as a global instance because it is in Prop, but the `f α` might match more than it should
instance Pure.toNonempty [Pure f] : [Nonempty α] → Nonempty (f α)
| ⟨a⟩ => ⟨pure a⟩
partial def forever {α β} [Applicative f] [Inhabited β] (a : f α) : f β :=
a *> forever a
James Gallicchio (Aug 25 2023 at 21:01):
it's still a bit odd to me that the nonempty can only be supplied by typeclass, instead of typeclass being a fallback for some optional syntax on def
s...
Last updated: Dec 20 2023 at 11:08 UTC