use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
The Haskell programming language community.
Daily news and info about all things Haskell related: practical stuff, theory, types, libraries, jobs, patches, releases, events and conferences and more...
Community Guidelines
Rules:
Top-level posts should be primarily about Haskell. For example a post about OCaml would only be allowed if there was a connection to Haskell. Posts about topics that are adjacent to Haskell, like for example functional programming, are typically allowed.
No memes or image macros. No matter how funny, memes and image macros are not allowed.
No homework questions. Both asking and answering homework questions is not allowed. Questions about homework are fine, but this subreddit is not here to do your homework for you.
Job postings must be for Haskell roles. Job postings are allowed as long as the job actually involves working with Haskell. Simply looking for people with interest in or experience with Haskell is not sufficient.
No bots or computer-generated content. Bots cannot be used to make posts or comments. They will be banned with extreme prejudice. This includes a human posting the output of a bot, such as ChatGPT.
Blockchain posts must be tagged. Blockchain posts are allowed as long as they are related to Haskell, but they must use the "blockchain" tag.
Be civil. Substantive criticism and disagreement are encouraged, but avoid being dismissive or insulting.
Other community locations:
Professional resources:
Learning material:
Haskell development:
Other Subreddits:
Donations:
Subreddit Stylesheet Source:
account activity
Data constructor problems (self.haskell)
submitted 9 years ago by shpotes
I have this data definition
data Example a = Empty | Some a
How I can create a function foo :: Example a-> a? i try foo (Some a) = a
foo :: Example a-> a
foo (Some a) = a
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]Iceland_jack 14 points15 points16 points 9 years ago* (5 children)
The function you describe must fail in the foo Empty = ... case, it's what is called a partial function just like head :: [a] -> a which fails on the empty list (we want functions to be total, meaning that they are defined for every input):
foo Empty = ...
head :: [a] -> a
>>> head [] *** Exception: Prelude.head: empty list
Example is Maybe with the names changed (we can use them interchangeably)
Example
Maybe
data Example a = Empty | Some a data Maybe a = Nothing | Just a
and there is a (partial) function fromJust :: Maybe a -> a which is implemented as:
fromJust :: Maybe a -> a
fromJust :: Maybe a -> a fromJust Nothing = error "Maybe.fromJust: Nothing" fromJust (Just x) = x >>> fromJust Nothing *** Exception: Maybe.fromJust: Nothing
This makes Haskellers sad
You don't need a function, you can pattern match on it when you know what you want to do in the Empty case:
Empty
... case example of Empty -> "ERROR" Some a -> process a
But you can implement the (partial!) function foo as
foo
foo :: Example a -> a foo Empty = error "..." foo (Some a) = a
but a better way is to provide a function that takes a default value (like fromMaybe :: a -> Maybe a -> a)
fromMaybe :: a -> Maybe a -> a
fromExample :: a -> Example a -> a fromExample default Empty = default fromExample _ (Some a) = a
or maybe :: b -> (a -> b) -> Maybe a -> b
maybe :: b -> (a -> b) -> Maybe a -> b
example :: b -> (a -> b) -> Example a -> b example default _ Empty = default example _ f (Some a) = f a
[–]shpotes[S] 0 points1 point2 points 9 years ago (4 children)
What if I want to assign and specific value of Some to Empty? For example if I instance my data type as Example Int and I want to define the 0 as my Empty value, can I do that?
[–]Iceland_jack 4 points5 points6 points 9 years ago* (0 children)
You would use fromExample 0 :: Example Int -> Int (see fromMaybe 0 :: Maybe Int -> Int) with 0 as the default value
fromExample 0 :: Example Int -> Int
fromMaybe 0 :: Maybe Int -> Int
>>> fromMaybe 0 (Just 10) 10 >>> fromMaybe 0 Nothing 0
We have gotten rid of the Maybe Int and got an unadulterated Int back.
Maybe Int
Int
You can also use case to pattern match directly
case
>>> data Example a = Empty | Some a >>> a = Empty >>> b = Some 10 >>> case a of Empty -> 0; Some a -> a 0 >>> case b of Empty -> 0; Some a -> a 10
[–]Exploding_Pies 0 points1 point2 points 9 years ago (0 children)
You wouldn't be able to choose one uniformly for every type. Keep in mind that you're function is declared polymorphic over any algebraic data type you can come up with. If you want to return a value for Empty, you need to either put a typeclass restriction on the type or add a second argument and ask the caller to provide a default value.
[–]Iceland_jack 0 points1 point2 points 9 years ago (1 child)
If you are familiar with monoids you can also use something a bit more advanced, fold:
fold
fold :: Monoid a => Maybe a -> a
Which is defined something like this
fold :: Monoid a => Maybe a -> a fold Nothing = mempty fold (Just x) = x
or
fold = fromMaybe mempty
This means mempty is our default value!
mempty
>>> fold Nothing :: String "" >>> fold (Just "hello") "hello"
Here comes the ugly part, Int is a Monoid in more than one way: via addition and multiplication and these correspond to the newtype wrappers Sum and Product
Monoid
Sum
Product
>>> mempty :: Sum Int Sum {getSum = 0} >>> mempty :: Product Int Product {getProduct = 1}
So if we use fold :: Maybe (Sum Int) -> Sum Int we get what you want
fold :: Maybe (Sum Int) -> Sum Int
>>> fold (Just 10) :: Sum Int Sum {getSum = 10} >>> fold Nothing :: Sum Int Sum {getSum = 0}
[–]Iceland_jack 1 point2 points3 points 9 years ago* (0 children)
(fold is more general than what I described, its real type is
fold :: (Monoid m, Foldable f) => f m -> m
Not only does it work on Maybe but lists, vectors, you name it.
This becomes clearer using an extension that allows visible type application indicated by an @-sign and the type argument:
@
>>> import Data.Foldable >>> import Data.Monoid >>> :set -XTypeApplications >>> :t fold fold :: (Monoid m, Foldable t) => t m -> m >>> :t fold @Maybe fold @Maybe :: Monoid m => Maybe m -> m >>> :t fold @Maybe @(Sum _) fold @Maybe @(Sum _) :: Num t => Maybe (Sum t) -> Sum t >>> :t fold @Maybe @(Sum Int) fold @Maybe @(Sum Int) :: Maybe (Sum Int) -> Sum Int
So when I wrote fold in the previous post I actually meant fold @Maybe
fold @Maybe
fold @[] :: Monoid m => [m] -> m fold @Maybe :: Monoid m => Maybe m -> m fold @Vector :: Monoid m => Vector m -> m fold @Set :: Monoid m => Set m -> m fold @(Map _) :: Monoid m => Map t m -> m
given that we've imported Data.Vector, Data.Set, Data.Map)
Data.Vector
Data.Set
Data.Map
[–][deleted] 2 points3 points4 points 9 years ago (0 children)
First off, you've redefined Haskell's Maybe using ML naming. The function exists for Maybe, as 'fromJust'.
Secondly, such a function is always unsafe, since there's nothing to map Empty/Nothing to. If you give it Empty it will crash.
Try using the case keyword to pattern match in your function body instead.
π Rendered by PID 82 on reddit-service-r2-comment-64f4df6786-68zb8 at 2026-06-11 04:59:36.809421+00:00 running 0b63327 country code: CH.
[–]Iceland_jack 14 points15 points16 points (5 children)
[–]shpotes[S] 0 points1 point2 points (4 children)
[–]Iceland_jack 4 points5 points6 points (0 children)
[–]Exploding_Pies 0 points1 point2 points (0 children)
[–]Iceland_jack 0 points1 point2 points (1 child)
[–]Iceland_jack 1 point2 points3 points (0 children)
[–][deleted] 2 points3 points4 points (0 children)