2009/3/13 Marcin Kosiba marcin.kos...@gmail.com:
On Thursday 12 March 2009, you wrote:
2009/3/12 Marcin Kosiba marcin.kos...@gmail.com:
Hi,
I'm doing a bit of research into mobility models and I'm currently
exploring implementation language choices for the simulator
(*snip*)
The
On Thu, Mar 12, 2009 at 8:45 PM, Antoine Latter aslat...@gmail.com wrote:
So the Ord instance is wrong for the PortNumber type? Well, maybe not
wrong.
It's out and out wrong. You get different results on machines of different
endianness. Now, this begs the question of why not just simply use
Sorry, maybe it I didn't made it clear enough.
Perhaps I'm misunderstanding something, but since one can infer types
in GHCI, that implies one can infer types in the GHC API; since Hint
wraps the GHC API, that implies one can infer types in Hint, doesn't
it? And indeed, there are functions to
Am Donnerstag, 12. März 2009 22:00 schrieb Martijn van Steenbergen:
Deniz Dogan wrote:
Then of course,
there's the downside that there's no connection to the language itself
in any way.
I usually go for names that don't have to do anything with the
application itself: GroteTrap
Hi Heikki,
Heikki Aitakangas wrote:
Is it possible to generate a unified documentation tree similar to
http://www.haskell.org/ghc/docs/latest/html/libraries/index.html from
packages installed via cabal from hackage? And if so, how does one go
about doing it?
This question was asked recently.
Hi Mark,
On Mar 13, 2009, at 3:54 AM, Mark Spezzano wrote:
I was wondering what the best way to implement Natural number would
be. Is there a package which already does this?
there are two packages on Hackage that implement natural numbers using
algebraic datatypes: 'numbers' has a module
Am Freitag, 13. März 2009 04:29 schrieb Benjamin L.Russell:
Consider the following logo:
Silver red monad.png
http://commons.wikimedia.org/wiki/File:Silver_red_monad.png
Can’t we choose something which is not connected to certain worldviews?
Best wishes,
Wolfgang
Am Freitag, 13. März 2009 05:09 schrieb Denis Bueno:
This works because every monad induces an Applicative instance in a
way I've ingested just enough wine to forget. =]
pure = return
(*) = ap
Best wishes,
Wolfgang
___
Haskell-Cafe mailing list
* Alexander Dunlap alexander.dun...@gmail.com [2009-03-12 20:01:57-0700]
Also, a lot of functions just take
Integers so it would be more of a pain to use.
AFAIK there are very few fuctions that take Integers. Many functions
take instances of Integral, but it's not a problem to make your own
Am Freitag, 13. März 2009 04:01 schrieb Alexander Dunlap:
2. Use the type
data Natural = Zero | Succ !Natural
[…]
In terms of speed, I think that [3] would be reasonably fast (unless
you do a ton of subtraction with bounds-checking) and [2] would
probably be quite slow, because you
Am Freitag, 13. März 2009 04:53 schrieb Brandon S. Allbery KF8NH:
On 2009 Mar 12, at 22:54, Mark Spezzano wrote:
I was wondering what the best way to implement Natural number would
be. Is there a package which already does this?
type-level on Hackage.
I think, the original poster wanted
On Friday 13 March 2009, you wrote:
2009/3/13 Marcin Kosiba marcin.kos...@gmail.com:
On Thursday 12 March 2009, you wrote:
2009/3/12 Marcin Kosiba marcin.kos...@gmail.com:
Hi,
I'm doing a bit of research into mobility models and I'm
currently exploring implementation language
Am Freitag, 13. März 2009 09:21 schrieb Roman Cheplyaka:
* Alexander Dunlap alexander.dun...@gmail.com [2009-03-12 20:01:57-0700]
Also, a lot of functions just take
Integers so it would be more of a pain to use.
AFAIK there are very few fuctions that take Integers. Many functions
take
2009/3/13 Marcin Kosiba marcin.kos...@gmail.com:
On Friday 13 March 2009, you wrote:
2009/3/13 Marcin Kosiba marcin.kos...@gmail.com:
On Thursday 12 March 2009, you wrote:
2009/3/12 Marcin Kosiba marcin.kos...@gmail.com:
Hi,
I'm doing a bit of research into mobility models and
Thomas Hartman wrote:
http://blog.patch-tag.com/2009/03/09/implicitparams-are-evil-thoughts-on-adapting-gitit/
I understand there are arguments for using IPs, but after this
experience, the ImplicitParams extension is a code smell for me.
It's not just you. Implicit parameters are a scourge
Thanks a lot for the detailed answer. I must admit, I haven't understood
it completely yet, so please excuse for probably naive questions.
As far as I see from the language defined in Incope.hs, there is only
support for the defined primitive functions (add, mult, if_, etc.).
Using additional
-- Forwarded message --
From: Alberto G. Corona agocor...@gmail.com
Date: 2009/3/13
Subject: Re: [Haskell-cafe] DSLs with {in,}equalities
To: Adam Vogt vogt.a...@gmail.com
You need an expression evaluator:
with
(+) (Const a) (Const b)= Const (a+b)
(*) (Const a) (Const b)= Const
Benjamin L.Russell dekudekup...@yahoo.com wrote:
balance
Stop right there. Any further word about what the Taiji means would
only make you look even more clueless. Take a scale if you want a
symbol for balance[1].
OTOH, laziness(yin) and strictness(yang) make a far better pair of
unified
even at the level of expressions you can be sure that inequalities hold. So
you can create an instance of Ord. for example:
(Sum x z) y | x== y z0 = True
|
here x and y can be expressions and == can have its own rules
with this you can compute symbolically, because
Jules Bean wrote:
Thomas Hartman wrote:
http://blog.patch-tag.com/2009/03/09/implicitparams-are-evil-thoughts-
on-adapting-gitit/
I understand there are arguments for using IPs, but after this
experience, the ImplicitParams extension is a code smell for me.
It's not just you. Implicit
On Thu, Mar 12, 2009 at 9:17 PM, Benjamin L. Russell
dekudekup...@yahoo.com wrote:
On Thu, 12 Mar 2009 09:11:15 -0500, Gregg Reynolds d...@mobileink.com
wrote:
I don't think so. Bad design will lose them (and many others), but
good design and cuteness are two different things.
It's also
I've unconciously conditioned myself to think about rabbits with nukes each
time I think about monads. Warm fuzzy things launching the missiles
indeed.
On Friday 13 March 2009 02.38.29 Richard O'Keefe wrote:
On 12 Mar 2009, at 11:08 pm, Satnam Singh wrote:
I agree that looking for a mascot
Hello,
Looking at Parsec 3 I see:
chainr1 :: (Stream s m t) = ParsecT s u m a -
ParsecT s u m (a - a - a) - ParsecT s u m a
chainr1 p op = scan where
scan = do x - p; rest x
rest x = (do f - op; y - scan; return (f x y)) | return x
But if I remove the type signature and let
On Fri, 13 Mar 2009 12:29:25 +0100, Achim Schneider bars...@web.de
wrote:
Benjamin L.Russell dekudekup...@yahoo.com wrote:
balance
Stop right there. Any further word about what the Taiji means would
only make you look even more clueless. Take a scale if you want a
symbol for balance[1].
Hallo,
On Fri, Mar 13, 2009 at 1:23 PM, Benjamin L. Russell
dekudekup...@yahoo.com wrote:
On Fri, 13 Mar 2009 12:29:25 +0100, Achim Schneider bars...@web.de
Water overcomes stone:
Shapeless, it requires no opening:
The benefit of taking no action.
Yet benefit without action,
And experience
2009/3/13 Martijn van Steenbergen mart...@van.steenbergen.nl:
Hello,
Looking at Parsec 3 I see:
chainr1 :: (Stream s m t) = ParsecT s u m a -
ParsecT s u m (a - a - a) - ParsecT s u m a
chainr1 p op = scan where
scan = do x - p; rest x
rest x = (do f - op; y - scan; return (f
Don Stewart ha scritto:
[...]
I think uvector only works with certain types that can be
unboxed, while storablevector works with all types that
instantiate Foreign.Storable.Storable. I don't know about
vector. From the description of vector, I have the
One of the nice feature of uvector
What about the Rabbit of Caerbannog[1]. Looks cute on first sight,
but upon further investigation turns out to be a vicious killer.
Useful to quench any rumors of Haskell being a toy language. You just
need to look a bit closer.
[1] http://en.wikipedia.org/wiki/Rabbit_of_Caerbannog
On Fri, Mar
Bonjour café,
Are there any functors f for which no point/pure/return :: a - f a exists?
Thank you,
Martijn.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Don Stewart ha scritto:
bulat.ziganshin:
Hello Don,
Wednesday, March 11, 2009, 12:12:07 AM, you wrote:
Right, so my point stands: there's no difference now. If you can write a
Storable instance, you can write a UA et al instance.
yes, if there is some class provided for this and not just
Hi café !
I googled for some kind of vim support for cabal but found nothing. I
mean syntax highlighting of .cabal and probably integration with
haskellmode. Did anyone hear about such thing?
Pavel
___
Haskell-Cafe mailing list
Benjamin L.Russell dekudekup...@yahoo.com wrote:
OTOH, laziness(yin) and strictness(yang) make a far better pair of
unified opposites than the schemeish eval and apply (which's outer
essences are both yang, changing to yin only by means of what they
execute[2]).
Indeed. But strictness
Roel van Dijk vandijk.r...@gmail.com wrote:
What about the Rabbit of Caerbannog[1]. Looks cute on first sight,
but upon further investigation turns out to be a vicious killer.
Useful to quench any rumors of Haskell being a toy language. You just
need to look a bit closer.
[1]
On Fri, Mar 13, 2009 at 03:18:15PM +0100, Martijn van Steenbergen wrote:
Are there any functors f for which no point/pure/return :: a - f a exists?
No. Choose an arbitrary element shape :: f () and define
point x = fmap (const x) shape
___
'An arbitrary element' means 'undefined will suffice'
point x = fmap (const x) undefined
2009/3/13 Ross Paterson r...@soi.city.ac.uk:
On Fri, Mar 13, 2009 at 03:18:15PM +0100, Martijn van Steenbergen wrote:
Are there any functors f for which no point/pure/return :: a - f a exists?
No.
Manlio Perillo ha scritto:
[...]
uvector package also suppors Complex and Rational, however the support
for these type is hard written, using a UAProd class, and requires
some boiler plate code (IMHO).
Correction: UAProd is not a class, sorry.
It is the UA constructor overloaded for a:*:b,
On 13 Mar 2009, at 14:32, Ross Paterson wrote:
On Fri, Mar 13, 2009 at 03:18:15PM +0100, Martijn van Steenbergen
wrote:
Are there any functors f for which no point/pure/return :: a - f a
exists?
No. Choose an arbitrary element shape :: f () and define
point x = fmap (const x)
On 2009 Mar 13, at 4:03, Martin Hofmann wrote:
That's true, inferring the type of a string is not the problem.
However,
I am not only interested in the top-level type, but also in the type
of
any arbitrary subexpression. Consider for example following recursive
definition:
I'm pretty sure
On Fri, Mar 13, 2009 at 02:32:23PM +, Ross Paterson wrote:
On Fri, Mar 13, 2009 at 03:18:15PM +0100, Martijn van Steenbergen wrote:
Are there any functors f for which no point/pure/return :: a - f a exists?
No. Choose an arbitrary element shape :: f () and define
point x =
On Fri, Mar 13, 2009 at 1:31 AM, Wolfgang Jeltsch
jelt...@informatik.tu-cottbus.de wrote:
When running the executable, nothing happens. The executable should show a
usage message instead. Where are the BASIC programs? I think, you have to
grab them from the source. They should be installed,
Eugene Kirpichov wrote:
'An arbitrary element' means 'undefined will suffice'
point x = fmap (const x) undefined
Prelude fmap (const True) undefined :: [Bool]
*** Exception: Prelude.undefined
Or is that not what you mean?
Martijn.
___
On Fri, Mar 13, 2009 at 05:35:31PM +0300, Eugene Kirpichov wrote:
'An arbitrary element' means 'undefined will suffice'
point x = fmap (const x) undefined
This is false.
Prelude fmap (const 1) [()]
[1]
Prelude fmap (const 1) undefined
*** Exception: Prelude.undefined
-Brent
On 2009 Mar 13, at 4:25, Wolfgang Jeltsch wrote:
Am Freitag, 13. März 2009 04:53 schrieb Brandon S. Allbery KF8NH:
On 2009 Mar 12, at 22:54, Mark Spezzano wrote:
I was wondering what the best way to implement Natural number would
be. Is there a package which already does this?
type-level on
On 2009 Mar 13, at 9:57, andy morris wrote:
(Currently the functions in Parsec have the more specific type as
Martijn says, but if they're generalised then I don't really see why
they need to be duplicated.)
Possibly so Parsec has decent performance on Haskell compilers that
don't do {-#
For most functors, that is equivalent to
point x = undefined
But by that logic, everything is a member of every typeclass...
--
Robin
On Fri, 13 Mar 2009 17:35:31 +0300
Eugene Kirpichov ekirpic...@gmail.com wrote:
'An arbitrary element' means 'undefined will suffice'
point x = fmap (const
On Fri, 13 Mar 2009 14:32:23 +
Ross Paterson r...@soi.city.ac.uk wrote:
On Fri, Mar 13, 2009 at 03:18:15PM +0100, Martijn van Steenbergen
wrote:
Are there any functors f for which no point/pure/return :: a - f a
exists?
No. Choose an arbitrary element shape :: f () and define
Well, yes; then, that means that an arbitrary element is also false:
you can't just take an arbitrary element and hope that works well.
Then the original question must be reformulated:
- Are there any functors for which there exists at least one
non-bottom value of type 'f a' for some a, but
2009/3/13 Marcin Kosiba marcin.kos...@gmail.com:
...
Threading the state is not the problem. Maybe this will help:
what I have now:
fsm world state = case state of
first -
do_stuff_one
(move_up, succ state)
second -
do_stuff_two
(move_left, succ state)
third -
On Thursday 12 March 2009 10:30:47 pm Robin Green wrote:
For most functors, that is equivalent to
point x = undefined
But by that logic, everything is a member of every typeclass...
There are some cases where expected laws will prevent that. For instance, If
you try to make a monad like:
On Fri, Mar 13, 2009 at 04:11:57PM +0100, Martijn van Steenbergen wrote:
Eugene Kirpichov wrote:
'An arbitrary element' means 'undefined will suffice'
point x = fmap (const x) undefined
Prelude fmap (const True) undefined :: [Bool]
*** Exception: Prelude.undefined
Or is that not what you
Brandon S. Allbery KF8NH wrote:
I'm pretty sure you can pull a typed AST out of ghc-api and query the
type of any node.
Thanks. I am relieved to hear that.
Could anybody tell me, where to start in the ghc-api? It's pretty hard,
when you don't know where to look. Hoogle doesn't know anything
Ross Paterson wrote:
No. Choose an arbitrary element shape :: f () and define
point x = fmap (const x) shape
Interesting. Is the arbitrariness of the shape some sort of evidence
that Pointed is not really a very useful class in its own right?
Certainly, the shape does matter if you
On Sat, 2009-03-14 at 02:12 +1000, Matthew Brecknell wrote:
Ross Paterson wrote:
No. Choose an arbitrary element shape :: f () and define
point x = fmap (const x) shape
Interesting. Is the arbitrariness of the shape some sort of evidence
that Pointed is not really a very useful
On Sat, Mar 14, 2009 at 02:12:45AM +1000, Matthew Brecknell wrote:
Ross Paterson wrote:
No. Choose an arbitrary element shape :: f () and define
point x = fmap (const x) shape
Interesting. Is the arbitrariness of the shape some sort of evidence
that Pointed is not really a very
manlio_perillo:
Don Stewart ha scritto:
bulat.ziganshin:
Hello Don,
Wednesday, March 11, 2009, 12:12:07 AM, you wrote:
Right, so my point stands: there's no difference now. If you can write a
Storable instance, you can write a UA et al instance.
yes, if there is some class provided for
Is it possible to generate a unified documentation tree similar to
http://www.haskell.org/ghc/docs/latest/html/libraries/index.html from
packages installed via cabal from hackage? And if so, how does one go
about doing it?
-- Heikki Aitakangas
___
On Friday 13 March 2009, Cristiano Paris wrote:
2009/3/13 Marcin Kosiba marcin.kos...@gmail.com:
...
Threading the state is not the problem. Maybe this will help:
what I have now:
fsm world state = case state of
first -
do_stuff_one
(move_up, succ state)
second -
Hi Martin,
Could anybody tell me, where to start in the ghc-api? It's pretty hard,
when you don't know where to look. Hoogle doesn't know anything about
it. I found following DT describing the core language, but as far as I
see, there are no type in there either.
I've been working on parsing
Don Stewart ha scritto:
[...]
You also have to add instance for UIO:
instance (RealFloat a, UIO a) = UIO (Complex a) where
hPutU h (UAComplex arr) = hPutU h arr
hGetU h = do arr - hGetU h
return (UAComplex arr)
With
Bryan O'Sullivan ha scritto:
[...]
text is not mature, and is based on the same modern fusion framework as
uvector and vector. It uses unpinned arrays, but provides functions for
dealing with foreign code.
What is the reason why you have decided to use unpinned arrays
(ByteArray#) instead
manlio_perillo:
Bryan O'Sullivan ha scritto:
[...]
text is not mature, and is based on the same modern fusion framework as
uvector and vector. It uses unpinned arrays, but provides functions for
dealing with foreign code.
What is the reason why you have decided to use unpinned arrays
tphyahoo:
Is there something like subRegex... something like =~ s/.../.../ in
perl... for haskell pcre Regexen?
I mean, subRegex from Text.Regex of course:
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/regex-compat
Thanks for any advice,
Basically, we should have it.
2009/3/13 Marcin Kosiba marcin.kos...@gmail.com:
Threading the state is not the problem. Maybe this will help:
what I have now:
fsm world state = case state of
first -
do_stuff_one
(move_up, succ state)
second -
do_stuff_two
(move_left, succ state)
third -
Hello Don,
Friday, March 13, 2009, 8:08:57 PM, you wrote:
What is the reason why you have decided to use unpinned arrays
(ByteArray#) instead of pinned arrays (Foreign.Ptr)?
They prevent heap fragmentation (and in general are faster).
you probably mean faster alloc/gc operations, everything
2009/3/13 Pavel Perikov peri...@gmail.com:
Hi café !
I googled for some kind of vim support for cabal but found nothing. I mean
syntax highlighting of .cabal and probably integration with haskellmode. Did
anyone hear about such thing?
Pavel
I've been wanting something like this as well,
Hi.
I'm sure this is a know bug, but I can't find details with Google.
The offending code is here:
http://hpaste.org/fastcgi/hpaste.fcgi/view?id=2362
When I execute the program I get:
uio: readChunkBU: can't read
What's the problem?
I'm using uvector from:
Am Freitag, 13. März 2009 21:18 schrieb Manlio Perillo:
Hi.
I'm sure this is a know bug, but I can't find details with Google.
The offending code is here:
http://hpaste.org/fastcgi/hpaste.fcgi/view?id=2362
When I execute the program I get:
uio: readChunkBU: can't read
What's the
As far as I know, the reason for this is that the UIO instance for
productions writes the two rows out sequentially to file, but
doesn't include any means to determine the length of the two halves
when it's loading up again. When you try to read the production back
in, it tries to read in two
UIO's also only a truly alpha idea as a proxy for bytestring/Binary
support.
Patches welcome.
pumpkingod:
As far as I know, the reason for this is that the UIO instance for
productions writes the two rows out sequentially to file, but
doesn't include any means to determine the length of the
2009/3/13 Marcin Kosiba marcin.kos...@gmail.com:
Hi,
I've already checked those out. I tried using your yield
implementation and
while it works, I couldn't get it to work with the state monad.
So while:
data RecPair a b = Nil | RP (b, a - RecPair a b)
yield x = Cont $ \k - RP
Daniel Peebles ha scritto:
As far as I know, the reason for this is that the UIO instance for
productions writes the two rows out sequentially to file, but
doesn't include any means to determine the length of the two halves
when it's loading up again. When you try to read the production back
in,
As far as I know, the reason for this is that the UIO instance for
productions writes the two rows out sequentially to file, but
doesn't include any means to determine the length of the two halves
when it's loading up again. When you try to read the production back
in, it tries to read in two
Daniel Fischer ha scritto:
[...]
Worked with uvector-0.1.0.1:
[...]
But not with uvector-0.2
[...]
The main difference is that in uvector 0.2, hPutBU does not write in the
file the length of the array; hGetBU simply use the file size.
let elemSize = sizeBU 1 (undefined :: e)
n -
manlio_perillo:
Daniel Fischer ha scritto:
[...]
Worked with uvector-0.1.0.1:
[...]
But not with uvector-0.2
[...]
The main difference is that in uvector 0.2, hPutBU does not write in the
file the length of the array; hGetBU simply use the file size.
let elemSize = sizeBU 1
Don Stewart ha scritto:
[...]
So, the patch is: just revert this change.
Or... use your own UIO instance. That's why it's a type class!
Why should I rewrite the UIO instance, if one already exists?
Anyway, for the background on this:
Tue Nov 18 08:44:46 PST 2008 Malcolm Wallace
Am Freitag, 13. März 2009 23:53 schrieb Don Stewart:
manlio_perillo:
Daniel Fischer ha scritto:
[...]
Worked with uvector-0.1.0.1:
[...]
But not with uvector-0.2
[...]
The main difference is that in uvector 0.2, hPutBU does not write in the
file the length of the array;
manlio_perillo:
Don Stewart ha scritto:
[...]
So, the patch is: just revert this change.
Or... use your own UIO instance. That's why it's a type class!
Why should I rewrite the UIO instance, if one already exists?
Oh, because you want different serialization semantics to the
(arbitrary)
The main issue seems to be that although the semantics of UIO may be
arbitrary, Wallace's patch actually broke deserialization for any
production-based UArr, and I'm not sure the benefits are worthwhile
(loading a file someone else sent you) given that endianness is
already not taken into account
I'd like to do away with UIO altogether though.
pumpkingod:
The main issue seems to be that although the semantics of UIO may be
arbitrary, Wallace's patch actually broke deserialization for any
production-based UArr, and I'm not sure the benefits are worthwhile
(loading a file someone else
NOTE: This message was originally posted to the subreddit in question
(and has been slightly modified), where I was told that I should post
the question on haskell-cafe. See
http://www.reddit.com/r/haskell_proposals/comments/847by/ask_relevance_to_google_summer_of_code/
I'm currently researching
On Fri, 13 Mar 2009, Benjamin L.Russell wrote:
Why not ask new users to identify letters in a random bitmapped image
of a string, as is commonly done?
I assume, because those images are
1) not accessible by blind people
2) can be decoded by spammers, since they know how the images are
On Mon, 9 Mar 2009, Alexander Dunlap wrote:
- uvector, storablevector and vector are all designed for dealing with
arrays. They *can* be used for characters/word8s but are not
specialized for that purpose, do not deal with Unicode at all, and are
probably worse at it. They are better for
On Tue, 10 Mar 2009, ariep wrote:
Problem instance
In my code, I use some monad transformers. I used to use the mtl package,
but I recently switched to the combination transformers/monads-tf
(mainly for the Applicative instances).
The same code also uses the haskeline library, for
On Tue, 10 Mar 2009, Manlio Perillo wrote:
After a quick search with Google, it seems that there is not yet an
official document for Style Guide for Haskell Code.
I was only able to found:
http://www.cs.caltech.edu/courses/cs11/material/haskell/misc/haskell_style_guide.html
On Tue, 10 Mar 2009, Conor McBride wrote:
Apologies for crossposting. Please forward this message
to individuals or lists who may be interested. In addition
to the recently advertised PhD position at Strathclyde on
Reusability and Dependent Types, I am delighted to
advertise the following PhD
On Wed, 11 Mar 2009, R J wrote:
foldl and foldr are defined as follows:
foldr :: (a - b - b) - b - [a] - b
foldr f e [] = e
foldr f e (x : xs) = f x (foldr f e xs)
foldl :: (b - a - b) - b - [a] - b
foldl f e [] = e
foldl f e (x
On Thu, 12 Mar 2009, Peter Verswyvelen wrote:
I think. Or is it defined in some other package?
The 'transformers' package has those instances.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
On Thu, 12 Mar 2009, Andrew Wagner wrote:
Can you expand on this a bit? I'm curious why you think this.
http://haskell.org/haskellwiki/Type_classes_are_for_reusability
We recently had a thread about that. I can't find it now.
___
Haskell-Cafe
88 matches
Mail list logo