[Agda] Record scoping issue
Jorn van Wijk
J.J.vanWijk at students.uu.nl
Tue Sep 6 18:00:48 CEST 2016
Hi,
{-
While modelling some structure using a record, I was wondering if the
following is possible in Agda:
Having a property of given fields, defined inside a record, but useable to
instantiate/construct later record fields.
In the following bogus example, doubleA is a 'property' of field a. In
turn, b relies on this property. So I would like to use double to construct
b instead of redefining double.
-}
module RecordScope where
open import Data.Nat
module Problem where
record R : Set where
field
a : ℕ
doubleA : ℕ
doubleA = a + a
field
b : ℕ
squareB : ℕ
squareB = b * b
field
c : ℕ
example : R
example =
record
{ a = 2 -- we don't double because we have yet to define a
; b = {!doubleA + a!} -- I would like to have doubleA in scope here;
even a is not in scope
; c = {!doubleA * squareB!} -- 'c' relies on doubleA and squareB
}
{-
In the above example, doubleA is not in scope at b (same for squareB and
doubleA at c). Is there any way around this, to still have one definition
of doubleA and squareB while maintaining the other benefits of this example.
Such that given some r : R, we can just open R r, and bring everything into
scope.
Towards solving this problem, I came up with a solution consisting of
nesting the definitions inside modules; each field block comes with a
potential module before it.
then when constructing a record we open the modules in a where block.
Since, as far as i know, there is no syntax to specify a where block for
each field. I defined a single where block and an anonymous module to
define the fields.
The above example can possible be desugared into:
-}
module Solution where
module R₀ where -- R₀ is anonymous or fresh and is not suppose to clash
with other modules
module R₁ (a : ℕ) where
doubleA : ℕ
doubleA = a + a
module R₂ (b : ℕ) where
squareB = b * b
record R : Set where
open R₀ public
field
a : ℕ
open R₁ a public
field
b : ℕ
open R₂ b public
field
c : ℕ
example : R
example =
record
{ a = a
; b = b
; c = c
}
where module _ where
open R₀
a : ℕ
a = 2
open R₁ a
b : ℕ
b = doubleA + a
open R₂ b
c : ℕ
c = doubleA * squareB
-- also, what does putting modules between fields have for functionality?:
weird : R
weird =
record
{ R₀
; a = 2 -- we don't double because we have yet to define a
; R₀.R₁ 2 hiding (module R₂) renaming (doubleA to doubleA') -- what is
the purpose of a module assignment here?
; b = 4 -- doubleA' not in scope here..
; R₀
; c = 3
}
--Or is there perhaps some other design pattern I should use to model the
problem?
Thanks for reading my post and kind regards,
Jorn
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.chalmers.se/pipermail/agda/attachments/20160906/8736bae4/attachment.html
More information about the Agda
mailing list