Polymorphic function over pairs of maybes.

Hello all: I'd like to right a function that could take a structure with type (random example): (Int, (String, (Int, Int))) and another where each individual value is a Maybe of the corresponding type, for example: (Maybe Int, (Maybe String, (Maybe Int, Maybe Int))) and perform a fromMaybe using the values to produce a new value with the original types. The catch is, I'd like to be able to do that for an n-deep structure with any type, without having to write a separate function for them. I'm not even sure that this is possible, but perhaps someone could explain how it is or isn't? -- Edward Amsden Undergraduate Computer Science Rochester Institute of Technology www.edwardamsden.com

Maybe something like this would work for you (requires the TypeFamilies extension). class FromMaybe a where type Maybe' a fromMaybe :: a -> Maybe' a -> a instance FromMaybe Int where type Maybe' Int = Maybe Int fromMaybe = Data.Maybe.fromMaybe instance FromMaybe String where type Maybe' String = Maybe String fromMaybe = Data.Maybe.fromMaybe instance (FromMaybe a, FromMaybe b) => FromMaybe (a, b) where type Maybe' (a, b) = (Maybe' a, Maybe' b) fromMaybe (x, y) (a, b) = (fromMaybe x a, fromMaybe y b) - Jake McArthur

On 28 December 2010 19:23, Edward Amsden
Hello all:
I'd like to right a function that could take a structure with type (random example):
(Int, (String, (Int, Int)))
and another where each individual value is a Maybe of the corresponding type, for example: (Maybe Int, (Maybe String, (Maybe Int, Maybe Int)))
and perform a fromMaybe using the values to produce a new value with the original types. The catch is, I'd like to be able to do that for an n-deep structure with any type, without having to write a separate function for them. I'm not even sure that this is possible, but perhaps someone could explain how it is or isn't?
Maybe this is possible with Strafunski or one of the generics libraries that lean in that direction (SYB, KURE, or Oleg Kiselyov's typecase), though I've never looked at descending into two terms at the same time even if they have the same "type shape". http://okmij.org/ftp/Haskell/typecast.html At a meta-level do you have a need for this, or is it just a curiosity? If it is for some real world situation, I suspect there are simpler ways of achieving the functionality you seem to want.

Although I don't understand it myself Oleg's deepest functor [1] seems
to be what you're looking for.
-deech
[1] http://okmij.org/ftp/Haskell/deepest-functor.lhs
On Tue, Dec 28, 2010 at 1:23 PM, Edward Amsden
Hello all:
I'd like to right a function that could take a structure with type (random example):
(Int, (String, (Int, Int)))
and another where each individual value is a Maybe of the corresponding type, for example: (Maybe Int, (Maybe String, (Maybe Int, Maybe Int)))
and perform a fromMaybe using the values to produce a new value with the original types. The catch is, I'd like to be able to do that for an n-deep structure with any type, without having to write a separate function for them. I'm not even sure that this is possible, but perhaps someone could explain how it is or isn't?
-- Edward Amsden Undergraduate Computer Science Rochester Institute of Technology www.edwardamsden.com
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Aditya: Not quite, because I'm actually looking to extract values from a functor (Maybe) with a default. Stephen: Thanks, I'll take a look at those. I do have a need for it. I'm writing a very similar library to Yampa. (I would be patching Yampa, but the code is a mess, so I decided to try starting from scratch.) Basically, I have a signal processing loop, where values are passed updated with a Maybe, representing whether there is or is not a change to the value. I could use a single Maybe around the whole thing, but that would require then re-updating a potentially large structure entirely. I want to be able to build a combinator that can combine two signal-fetching actions into a larger one: IO (Maybe a) -> IO (...) -> IO (Maybe a, (...)) and then an action that could, given the previous value: (a, (...)) update any places in this chain of pairs where the Maybe is not Nothing. Jake: I'd prefer to not have to define class instances for the types. It would get tedious and awkward quickly. (See above for a description of what I'm looking for.) -- Edward Amsden Undergraduate Computer Science Rochester Institute of Technology www.edwardamsden.com

Basically, I have a signal processing loop, where values are passed updated with a Maybe, representing whether there is or is not a change to the value. I could use a single Maybe around the whole thing, but that would require then re-updating a potentially large structure entirely. I want to be able to build a combinator that can combine two signal-fetching actions into a larger one:
IO (Maybe a) -> IO (...) -> IO (Maybe a, (...))
and then an action that could, given the previous value: (a, (...))
update any places in this chain of pairs where the Maybe is not Nothing.
Sounds like you want a generic diff: http://hackage.haskell.org/package/gdiff-1.0 Cheers, Sterl

On 28 December 2010 21:44, Edward Amsden
I'm writing a very similar library to Yampa. (I would be patching Yampa, but the code is a mess, so I decided to try starting from scratch.) Basically, I have a signal processing loop, where values are passed updated with a Maybe, representing whether there is or is not a change to the value. I could use a single Maybe around the whole thing, but that would require then re-updating a potentially large structure entirely. I want to be able to build a combinator that can combine two signal-fetching actions into a larger one:
Hi Edward That's a tough proposition - phrased in a different way, you want syntax (i.e algebraic data types) with holes. Functors (List, Data.Sequence, ...) and Bifunctors (pairs and Either, ...) have obvious holes, and working with holey things is possible[*] but its probably way too far out for signal processing where you have efficiency concerns. Is it common for Reactive libraries like Yampa to operate on a large "World" datatype - rather than streams of signals of some atomic unit like Double? If it were me, I'd want to answer this question first before attempting to represent it. [*] See Conor McBride's "Clowns and Jokers" for instance: http://personal.cis.strath.ac.uk/~conor/Dissect.pdf

Edward Amsden schrieb:
Aditya: Not quite, because I'm actually looking to extract values from a functor (Maybe) with a default.
Stephen: Thanks, I'll take a look at those. I do have a need for it. I'm writing a very similar library to Yampa. (I would be patching Yampa, but the code is a mess, so I decided to try starting from scratch.) Basically, I have a signal processing loop, where values are passed updated with a Maybe, representing whether there is or is not a change to the value.
Hm, I have written a lot of signal processing stuff in Haskell (see packages synthesizer-core, synthesizer-llvm etc.), but so far I did not need to cope with all Maybes in a data structure at once. Does it happen very often for you, that a value does not change? I only need a Maybe for showing when a signal stops. But every signal processor maintains its own Maybe (synthesizer-core:Synthesizer.Signal.State, Synthesizer.Process.Causal). Btw. there is also haskell-art@lurk.org mailing list for discussing (audio) signal processing issues.

On Tue, Dec 28, 2010 at 21:23, Edward Amsden
(Int, (String, (Int, Int)))
and another where each individual value is a Maybe of the corresponding type, for example: (Maybe Int, (Maybe String, (Maybe Int, Maybe Int)))
This example demonstrates exactly why you might want to avoid doing this... if you apply Maybe as deeply inside type constructors as possible, you actually get (Maybe Int, ([Maybe Char], (Maybe Int, Maybe Int))) and in general you may not know or care whether a type is "atomic" or not. There may be a way which works if you specify the target type as well.
participants (7)
-
aditya siram
-
Edward Amsden
-
Henning Thielemann
-
Jake McArthur
-
Max Rabkin
-
Stephen Tetley
-
Sterling Clover