[Agda] stdlib for practical programming
Dmytro Starosud
d.starosud at gmail.com
Fri Sep 27 20:57:49 CEST 2013
Great! Thank you Andreas
That's exactly what I was looking for.
Best regards,
Dmytro
2013/9/27 Andreas Abel <andreas.abel at ifi.lmu.de>:
> Hej Dmytro,
>
> I would be happy if someone would take over the Agda Prelude and develop it
> further. It was the Master project of Frederic Kettelhoit, but it seems he
> is no longer maintaining it.
>
> The latest version is on github:
>
> https://github.com/fkettelhoit/agda-prelude
>
> Maybe you can get into contact with Frederic about contributing, or you fork
> it and develop it further...
>
> Cheers,
> Andreas (from ICFP)
>
>
> On 27.09.2013 14:34, Dmytro Starosud wrote:
>>
>> Ok, thank you.
>> I've understood, will implement my own Prelude.
>>
>> P.S. Just want to note, that I wasn't saying Agda cannot something or
>> isn't powerful enough, the same for Standard Library. I just asked if
>> someone had already written "Prelude" library for practical
>> programming. For me it would be more convenient to use uniform way
>> instead of reinvented one. But now I see everyone does it :-)
>>
>> Best regards,
>> Dmytro
>>
>> 2013/9/27 Sergei Meshveliani <mechvel at botik.ru>:
>>>
>>> On Thu, 2013-09-26 at 22:44 +0300, Dmytro Starosud wrote:
>>>>
>>>> OK, I see I should have been more precise.
>>>> Yes, Standard library is "some library" but it doesn't allow enough
>>>> level of overloading.
>>>> What I need? A lot of stuff.
>>>> In particular I need map (fmap, _<$>_ whatever) function which will
>>>> work for any functor (Maybe, List, Vector, Product, mapable; IMapable
>>>> whatever).
>>>
>>>
>>> In Haskell this is achieved by the
>>> language feature of constructor classes.
>>>
>>> For example, Functor is a constructor class defined in the Haskell's
>>> library:
>>>
>>> class Functor c where fmap :: (a → b) → c a → c b
>>> -- fmap f (c a) --> c (f a)
>>>
>>> -- if I recall correctly!
>>> Here c ranges over unary type constructors.
>>> For example, c may be List, Maybe, ...
>>>
>>> I think that Agda does not need any additional language feature for
>>> this. This notion of Functor
>>> (let us call it FMap, because I am not sure that Haskell's `Functor'
>>> means something close to Functor of the category theory)
>>>
>>> is easily expressed via dependent types and records:
>>>
>>> record FMap (Cons : Set → Set) : Set (suc 0ℓ)
>>> where
>>> field fmap : {A B : Set} → (f : A → B) → Cons A → Cons B
>>>
>>> (I skip the Level arguments, so far).
>>> Here Cons correponds to `c' in Functor of the Haskell library.
>>>
>>> This c FMap an be set into Standard library.
>>>
>>> But I suspect that Standard library already has something for this,
>>> may be something better.
>>>
>>> Who knows, please, has it?
>>>
>>> Anyway here is an example of using overloading for fmap via the above
>>> FMap `class':
>>>
>>> ---------------------------------------------------------------------
>>> module FMap where
>>> open import Level using (suc) renaming (zero to 0ℓ)
>>> open import Data.Bool using (Bool; true; false)
>>> open import Data.Nat using (ℕ)
>>> open import Data.Product using (_×_; _,_)
>>> open import Data.List using (List; []; _∷_)
>>> open import Data.Maybe using (Maybe; just; nothing)
>>>
>>> -- First, define various instances for FMap.
>>> -- Such instances can be easily defined and set into the library:
>>>
>>> listFMap : FMap List -- here Cons == List
>>> listFMap = record{ fmap = fmap-l }
>>> where
>>> fmap-l : {A B : Set} → (f : A → B) → List A → List B
>>> fmap-l _ [] = []
>>> fmap-l f (x ∷ xs) = (f x) ∷ (fmap-l f xs)
>>>
>>> maybeFMap : FMap Maybe -- here Cons == Maybe
>>> maybeFMap = record{ fmap = fmap-mb }
>>> where
>>> fmap-mb : {A B : Set} → (f : A → B) → Maybe A → Maybe B
>>> fmap-mb f nothing = nothing
>>> fmap-mb f (just a) = just (f a)
>>>
>>> ---------------------------------------------------------------------------
>>>
>>> Example of usage:
>>>
>>> g : Maybe Bool → Maybe ℕ → Maybe ℕ × Maybe Bool
>>> g mbBoo mbN = (fmap f mbBoo , fmap h mbN)
>>> where
>>> open FMap maybeFMap
>>>
>>> f : Bool → ℕ
>>> f true = 1
>>> f false = 0
>>>
>>> h : ℕ → Bool
>>> h 1 = true
>>> h _ = false
>>>
>>> We see that fmap is used as overloaded.
>>>
>>>
>>>> I don't want import renaming ten modules just to do some simple things.
>>>> I was asking for library, which simplifies all this work.
>>>> e.g. I would like following:
>>>>
>>>> open import Prelude -- Prelude is this wanted "some library"
>>>> {- many useful stuff here -}
>>>>
>>>> instead of:
>>>>
>>>> open import Level renaming (zero to zeroL; suc to sucL; \lub to \lubL)
>>>> open import Data.Nat renaming (zero to zeroN; suc to sucN; \lub to
>>>> \lubN; ...)
>>>> open import Data.List renaming (map to mapL; foldr to foldrL; ...)
>>>> open import Data.Vector renaming (map to mapV; foldr to foldrV; ...)
>>>> open import Data.Product renaming (map to mapP; ...)
>>>> etc. ...
>>>> etc. ...
>>>> etc. ...
>>>>
>>>> {- many useful stuff here -}
>>>>
>>>
>>> This `sugar' can (probably) be done by
>>>
>>> importing `classes' (done as records) and instances
>>> instead of separate functions.
>>>
>>> If Haskell and its library is considered as all right in this import
>>> matters, what is wrong with the Agda library in this point?
>>>
>>> For example, instead of zero and suc, one can import
>>> DistributiveLattice and its several instances
>>> (NatProp.distributiveLattice, Foo.distributiveLattice, ...)
>>>
>>> (a contrived example)
>>> and then to use overloading by open DistributiveLattice {{...}}
>>> and such.
>>> This will give importing items by _groups_.
>>>
>>> For example, 0#, 1# _+_; _*_ do not need to be renamed, because one
>>> can import the `classs' RingWithOne and several its instances.
>>>
>>> Introducing more `classes' and instances will support this style
>>> further.
>>>
>>> If I needed a single module Prelude
>>>
>>> which exports "everything I may needed", I could try to write
>>>
>>> module MyPrelude where
>>> open import Foo1 using (...) renaming (...)
>>> open import Foo2 using (...) renaming (...)
>>> ...
>>> somewhat use "open ... public",
>>>
>>> -- and do most of the import by `classes' and instances.
>>>
>>> I hope,
>>> this will join and re-export the needed things.
>>>
>>> I used this approach in Haskell to create a union DPrelude of
>>> MyProperPrelude and a large part of Standard library.
>>>
>>> How people think, will a similar approach work in Agda?
>>>
>>> (And as to my personal taste, I (currently) prefer to specify explicitly
>>> what is imported from each small module, because this way it is easier
>>> to control, to debug, to maintain
>>> ).
>>>
>>> Regards,
>>>
>>> ------
>>> Sergei
>>>
>>>
>>>
>>>
>>>
>>>
>> _______________________________________________
>> Agda mailing list
>> Agda at lists.chalmers.se
>> https://lists.chalmers.se/mailman/listinfo/agda
>>
>
>
> --
> Andreas Abel <>< Du bist der geliebte Mensch.
>
> Theoretical Computer Science, University of Munich
> Oettingenstr. 67, D-80538 Munich, GERMANY
>
> andreas.abel at ifi.lmu.de
> http://www2.tcs.ifi.lmu.de/~abel/
More information about the Agda
mailing list