Max heap in Haskell












1












$begingroup$


I wrote a (max) heap in Haskell which is balanced after every (public) operation. Not based on any documentation. Focus is on:




  • speed, that is the right time-complexities (not necessarily optimal);

  • easy to understand, so no Maybe's, Monads or symbols a beginner is unfamiliar with.



         ******* 4
*
******* 6
* *
* ******* 2
*
8
*
* ******* 3
* *
******* 7
*
* *******
* *
******* 5
*
******* 1



Would like it to be reviewed.



module Heap (insert, 
size,
deleteMax,
getMax,
fromList,
toList,
isEmpty,
empty,
singleton,
member) where


data Heap a = Empty | Node a Int (Heap a) (Heap a)


-- Insert an element to the heap.
insert :: Ord a => a -> Heap a -> Heap a
insert x Empty = Node x 1 Empty Empty
insert x (Node t n l r)
| x > t && size l > size r = Node x (n + 1) l (insert t r)
| x > t = Node x (n + 1) (insert t l) r
| x <= t && size l > size r = Node t (n + 1) l (insert x r)
| x <= t = Node t (n + 1) (insert x l) r


-- Checks if a heap is empty.
isEmpty :: Ord a => Heap a -> Bool
isEmpty Empty = True
isEmpty _ = False


-- Gives the empty heap.
empty :: Ord a => Heap a
empty = Empty


-- Creates a heap from a list.
fromList :: Ord a => [a] -> Heap a
fromList ls = foldr insert Empty ls


-- Checks if an element is a member of the heap.
member :: Ord a => a -> Heap a -> Bool
member x Empty = False
member x (Node t _ l r)
| x >= t = x == t
| otherwise = member x l || member x r


-- Turns the heap into a list.
toList :: Ord a => Heap a -> [a]
toList Empty =
toList (Node t _ l r) = (t : toList l) ++ (toList r)


-- Deletes an element from a heap which doesn't have any
-- smaller elements in a left or right heap. The mentioned
-- element together with the new heap are returned.
deleteBottom :: Ord a => Heap a -> (a, Heap a)
deleteBottom (Node t _ Empty Empty) = (t, Empty)
deleteBottom (Node t n l r)
| size l < size r = (x1, Node t (n - 1) l r')
| otherwise = (x2, Node t (n - 1) l' r)
where
(x1, r') = deleteBottom r
(x2, l') = deleteBottom l


-- Delete the largest element in the heap. The largest element
-- together with the new heap are returned.
-- Doesn't check for non-emptiness, therefore unsafe.
deleteMax :: Ord a => Heap a -> (a, Heap a)
deleteMax (Node t _ Empty Empty) = (t, Empty)
deleteMax (Node t n l r) = (t, merge x l' r')
where
(x, Node _ _ l' r') = deleteBottom (Node t n l r)


-- Create a heap from a single element.
singleton :: Ord a => a -> Heap a
singleton x = insert x Empty


-- An element x and two heaps A and B for which holds:
-- |size A - size B| <= 1.
-- Returns a new heap where x, A and B are glued together.
merge :: Ord a => a -> Heap a -> Heap a -> Heap a
merge x Empty Empty = singleton x
merge x (Node t _ Empty Empty) Empty
| x < t = Node t 2 (singleton x) Empty
| otherwise = Node x 2 (singleton t) Empty
merge x Empty (Node t _ Empty Empty)
| x < t = Node t 2 Empty (singleton x)
| otherwise = Node x 2 Empty (singleton t)
merge x (Node t n l r) (Node t' n' l' r')
| x >= t && x >= t' = Node x new_n (Node t n l r) (Node t' n' l' r')
| t >= x && t >= t' = Node t new_n (merge x l r) (Node t' n' l' r')
| otherwise = Node t' new_n (Node t n l r) (merge x l' r')
where
new_n = 1 + n + n'


-- Returns the number of elements in a heap.
size :: Ord a => Heap a -> Int
size Empty = 0
size (Node _ n _ _) = n


-- Get the largest element in a non-empty heap.
-- Doesn't check for non-emptiness, therefore unsafe.
getMax :: Ord a => Heap a -> a
getMax (Node t _ _ _) = t


instance (Show a) => Show (Heap a) where
show tr = ((++) "n" . unlines . snd . toLines) tr

where

toLines :: (Show a) => Heap a -> (Int, [String])
toLines Empty = (0, [""])
toLines (Node t _ Empty Empty) = (0, [" " ++ show t])
toLines (Node t _ l r) = (ln + 1, lv_new ++ [" *"] ++ [" " ++ show t] ++ [" *"] ++ rv_new)
where
(il, lv) = toLines l
(ir, rv) = toLines r
ln = length lv
rn = length rv
lv_sub = (replicate il " ") ++ [" *******"] ++ (replicate (ln - il) " * ")
rv_sub = (replicate ir " * ") ++ [" *******"] ++ (replicate (rn - ir) " ")
lv_new = zipWith (++) lv_sub lv
rv_new = zipWith (++) rv_sub rv









share|improve this question









New contributor




Elmex80s is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$












  • $begingroup$
    Welcome to Code Review. Is there a specific reason why you don't want to use Maybe and therefore get partial functions? Also, is that Show instance intended?
    $endgroup$
    – Zeta
    6 hours ago


















1












$begingroup$


I wrote a (max) heap in Haskell which is balanced after every (public) operation. Not based on any documentation. Focus is on:




  • speed, that is the right time-complexities (not necessarily optimal);

  • easy to understand, so no Maybe's, Monads or symbols a beginner is unfamiliar with.



         ******* 4
*
******* 6
* *
* ******* 2
*
8
*
* ******* 3
* *
******* 7
*
* *******
* *
******* 5
*
******* 1



Would like it to be reviewed.



module Heap (insert, 
size,
deleteMax,
getMax,
fromList,
toList,
isEmpty,
empty,
singleton,
member) where


data Heap a = Empty | Node a Int (Heap a) (Heap a)


-- Insert an element to the heap.
insert :: Ord a => a -> Heap a -> Heap a
insert x Empty = Node x 1 Empty Empty
insert x (Node t n l r)
| x > t && size l > size r = Node x (n + 1) l (insert t r)
| x > t = Node x (n + 1) (insert t l) r
| x <= t && size l > size r = Node t (n + 1) l (insert x r)
| x <= t = Node t (n + 1) (insert x l) r


-- Checks if a heap is empty.
isEmpty :: Ord a => Heap a -> Bool
isEmpty Empty = True
isEmpty _ = False


-- Gives the empty heap.
empty :: Ord a => Heap a
empty = Empty


-- Creates a heap from a list.
fromList :: Ord a => [a] -> Heap a
fromList ls = foldr insert Empty ls


-- Checks if an element is a member of the heap.
member :: Ord a => a -> Heap a -> Bool
member x Empty = False
member x (Node t _ l r)
| x >= t = x == t
| otherwise = member x l || member x r


-- Turns the heap into a list.
toList :: Ord a => Heap a -> [a]
toList Empty =
toList (Node t _ l r) = (t : toList l) ++ (toList r)


-- Deletes an element from a heap which doesn't have any
-- smaller elements in a left or right heap. The mentioned
-- element together with the new heap are returned.
deleteBottom :: Ord a => Heap a -> (a, Heap a)
deleteBottom (Node t _ Empty Empty) = (t, Empty)
deleteBottom (Node t n l r)
| size l < size r = (x1, Node t (n - 1) l r')
| otherwise = (x2, Node t (n - 1) l' r)
where
(x1, r') = deleteBottom r
(x2, l') = deleteBottom l


-- Delete the largest element in the heap. The largest element
-- together with the new heap are returned.
-- Doesn't check for non-emptiness, therefore unsafe.
deleteMax :: Ord a => Heap a -> (a, Heap a)
deleteMax (Node t _ Empty Empty) = (t, Empty)
deleteMax (Node t n l r) = (t, merge x l' r')
where
(x, Node _ _ l' r') = deleteBottom (Node t n l r)


-- Create a heap from a single element.
singleton :: Ord a => a -> Heap a
singleton x = insert x Empty


-- An element x and two heaps A and B for which holds:
-- |size A - size B| <= 1.
-- Returns a new heap where x, A and B are glued together.
merge :: Ord a => a -> Heap a -> Heap a -> Heap a
merge x Empty Empty = singleton x
merge x (Node t _ Empty Empty) Empty
| x < t = Node t 2 (singleton x) Empty
| otherwise = Node x 2 (singleton t) Empty
merge x Empty (Node t _ Empty Empty)
| x < t = Node t 2 Empty (singleton x)
| otherwise = Node x 2 Empty (singleton t)
merge x (Node t n l r) (Node t' n' l' r')
| x >= t && x >= t' = Node x new_n (Node t n l r) (Node t' n' l' r')
| t >= x && t >= t' = Node t new_n (merge x l r) (Node t' n' l' r')
| otherwise = Node t' new_n (Node t n l r) (merge x l' r')
where
new_n = 1 + n + n'


-- Returns the number of elements in a heap.
size :: Ord a => Heap a -> Int
size Empty = 0
size (Node _ n _ _) = n


-- Get the largest element in a non-empty heap.
-- Doesn't check for non-emptiness, therefore unsafe.
getMax :: Ord a => Heap a -> a
getMax (Node t _ _ _) = t


instance (Show a) => Show (Heap a) where
show tr = ((++) "n" . unlines . snd . toLines) tr

where

toLines :: (Show a) => Heap a -> (Int, [String])
toLines Empty = (0, [""])
toLines (Node t _ Empty Empty) = (0, [" " ++ show t])
toLines (Node t _ l r) = (ln + 1, lv_new ++ [" *"] ++ [" " ++ show t] ++ [" *"] ++ rv_new)
where
(il, lv) = toLines l
(ir, rv) = toLines r
ln = length lv
rn = length rv
lv_sub = (replicate il " ") ++ [" *******"] ++ (replicate (ln - il) " * ")
rv_sub = (replicate ir " * ") ++ [" *******"] ++ (replicate (rn - ir) " ")
lv_new = zipWith (++) lv_sub lv
rv_new = zipWith (++) rv_sub rv









share|improve this question









New contributor




Elmex80s is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$












  • $begingroup$
    Welcome to Code Review. Is there a specific reason why you don't want to use Maybe and therefore get partial functions? Also, is that Show instance intended?
    $endgroup$
    – Zeta
    6 hours ago
















1












1








1





$begingroup$


I wrote a (max) heap in Haskell which is balanced after every (public) operation. Not based on any documentation. Focus is on:




  • speed, that is the right time-complexities (not necessarily optimal);

  • easy to understand, so no Maybe's, Monads or symbols a beginner is unfamiliar with.



         ******* 4
*
******* 6
* *
* ******* 2
*
8
*
* ******* 3
* *
******* 7
*
* *******
* *
******* 5
*
******* 1



Would like it to be reviewed.



module Heap (insert, 
size,
deleteMax,
getMax,
fromList,
toList,
isEmpty,
empty,
singleton,
member) where


data Heap a = Empty | Node a Int (Heap a) (Heap a)


-- Insert an element to the heap.
insert :: Ord a => a -> Heap a -> Heap a
insert x Empty = Node x 1 Empty Empty
insert x (Node t n l r)
| x > t && size l > size r = Node x (n + 1) l (insert t r)
| x > t = Node x (n + 1) (insert t l) r
| x <= t && size l > size r = Node t (n + 1) l (insert x r)
| x <= t = Node t (n + 1) (insert x l) r


-- Checks if a heap is empty.
isEmpty :: Ord a => Heap a -> Bool
isEmpty Empty = True
isEmpty _ = False


-- Gives the empty heap.
empty :: Ord a => Heap a
empty = Empty


-- Creates a heap from a list.
fromList :: Ord a => [a] -> Heap a
fromList ls = foldr insert Empty ls


-- Checks if an element is a member of the heap.
member :: Ord a => a -> Heap a -> Bool
member x Empty = False
member x (Node t _ l r)
| x >= t = x == t
| otherwise = member x l || member x r


-- Turns the heap into a list.
toList :: Ord a => Heap a -> [a]
toList Empty =
toList (Node t _ l r) = (t : toList l) ++ (toList r)


-- Deletes an element from a heap which doesn't have any
-- smaller elements in a left or right heap. The mentioned
-- element together with the new heap are returned.
deleteBottom :: Ord a => Heap a -> (a, Heap a)
deleteBottom (Node t _ Empty Empty) = (t, Empty)
deleteBottom (Node t n l r)
| size l < size r = (x1, Node t (n - 1) l r')
| otherwise = (x2, Node t (n - 1) l' r)
where
(x1, r') = deleteBottom r
(x2, l') = deleteBottom l


-- Delete the largest element in the heap. The largest element
-- together with the new heap are returned.
-- Doesn't check for non-emptiness, therefore unsafe.
deleteMax :: Ord a => Heap a -> (a, Heap a)
deleteMax (Node t _ Empty Empty) = (t, Empty)
deleteMax (Node t n l r) = (t, merge x l' r')
where
(x, Node _ _ l' r') = deleteBottom (Node t n l r)


-- Create a heap from a single element.
singleton :: Ord a => a -> Heap a
singleton x = insert x Empty


-- An element x and two heaps A and B for which holds:
-- |size A - size B| <= 1.
-- Returns a new heap where x, A and B are glued together.
merge :: Ord a => a -> Heap a -> Heap a -> Heap a
merge x Empty Empty = singleton x
merge x (Node t _ Empty Empty) Empty
| x < t = Node t 2 (singleton x) Empty
| otherwise = Node x 2 (singleton t) Empty
merge x Empty (Node t _ Empty Empty)
| x < t = Node t 2 Empty (singleton x)
| otherwise = Node x 2 Empty (singleton t)
merge x (Node t n l r) (Node t' n' l' r')
| x >= t && x >= t' = Node x new_n (Node t n l r) (Node t' n' l' r')
| t >= x && t >= t' = Node t new_n (merge x l r) (Node t' n' l' r')
| otherwise = Node t' new_n (Node t n l r) (merge x l' r')
where
new_n = 1 + n + n'


-- Returns the number of elements in a heap.
size :: Ord a => Heap a -> Int
size Empty = 0
size (Node _ n _ _) = n


-- Get the largest element in a non-empty heap.
-- Doesn't check for non-emptiness, therefore unsafe.
getMax :: Ord a => Heap a -> a
getMax (Node t _ _ _) = t


instance (Show a) => Show (Heap a) where
show tr = ((++) "n" . unlines . snd . toLines) tr

where

toLines :: (Show a) => Heap a -> (Int, [String])
toLines Empty = (0, [""])
toLines (Node t _ Empty Empty) = (0, [" " ++ show t])
toLines (Node t _ l r) = (ln + 1, lv_new ++ [" *"] ++ [" " ++ show t] ++ [" *"] ++ rv_new)
where
(il, lv) = toLines l
(ir, rv) = toLines r
ln = length lv
rn = length rv
lv_sub = (replicate il " ") ++ [" *******"] ++ (replicate (ln - il) " * ")
rv_sub = (replicate ir " * ") ++ [" *******"] ++ (replicate (rn - ir) " ")
lv_new = zipWith (++) lv_sub lv
rv_new = zipWith (++) rv_sub rv









share|improve this question









New contributor




Elmex80s is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$




I wrote a (max) heap in Haskell which is balanced after every (public) operation. Not based on any documentation. Focus is on:




  • speed, that is the right time-complexities (not necessarily optimal);

  • easy to understand, so no Maybe's, Monads or symbols a beginner is unfamiliar with.



         ******* 4
*
******* 6
* *
* ******* 2
*
8
*
* ******* 3
* *
******* 7
*
* *******
* *
******* 5
*
******* 1



Would like it to be reviewed.



module Heap (insert, 
size,
deleteMax,
getMax,
fromList,
toList,
isEmpty,
empty,
singleton,
member) where


data Heap a = Empty | Node a Int (Heap a) (Heap a)


-- Insert an element to the heap.
insert :: Ord a => a -> Heap a -> Heap a
insert x Empty = Node x 1 Empty Empty
insert x (Node t n l r)
| x > t && size l > size r = Node x (n + 1) l (insert t r)
| x > t = Node x (n + 1) (insert t l) r
| x <= t && size l > size r = Node t (n + 1) l (insert x r)
| x <= t = Node t (n + 1) (insert x l) r


-- Checks if a heap is empty.
isEmpty :: Ord a => Heap a -> Bool
isEmpty Empty = True
isEmpty _ = False


-- Gives the empty heap.
empty :: Ord a => Heap a
empty = Empty


-- Creates a heap from a list.
fromList :: Ord a => [a] -> Heap a
fromList ls = foldr insert Empty ls


-- Checks if an element is a member of the heap.
member :: Ord a => a -> Heap a -> Bool
member x Empty = False
member x (Node t _ l r)
| x >= t = x == t
| otherwise = member x l || member x r


-- Turns the heap into a list.
toList :: Ord a => Heap a -> [a]
toList Empty =
toList (Node t _ l r) = (t : toList l) ++ (toList r)


-- Deletes an element from a heap which doesn't have any
-- smaller elements in a left or right heap. The mentioned
-- element together with the new heap are returned.
deleteBottom :: Ord a => Heap a -> (a, Heap a)
deleteBottom (Node t _ Empty Empty) = (t, Empty)
deleteBottom (Node t n l r)
| size l < size r = (x1, Node t (n - 1) l r')
| otherwise = (x2, Node t (n - 1) l' r)
where
(x1, r') = deleteBottom r
(x2, l') = deleteBottom l


-- Delete the largest element in the heap. The largest element
-- together with the new heap are returned.
-- Doesn't check for non-emptiness, therefore unsafe.
deleteMax :: Ord a => Heap a -> (a, Heap a)
deleteMax (Node t _ Empty Empty) = (t, Empty)
deleteMax (Node t n l r) = (t, merge x l' r')
where
(x, Node _ _ l' r') = deleteBottom (Node t n l r)


-- Create a heap from a single element.
singleton :: Ord a => a -> Heap a
singleton x = insert x Empty


-- An element x and two heaps A and B for which holds:
-- |size A - size B| <= 1.
-- Returns a new heap where x, A and B are glued together.
merge :: Ord a => a -> Heap a -> Heap a -> Heap a
merge x Empty Empty = singleton x
merge x (Node t _ Empty Empty) Empty
| x < t = Node t 2 (singleton x) Empty
| otherwise = Node x 2 (singleton t) Empty
merge x Empty (Node t _ Empty Empty)
| x < t = Node t 2 Empty (singleton x)
| otherwise = Node x 2 Empty (singleton t)
merge x (Node t n l r) (Node t' n' l' r')
| x >= t && x >= t' = Node x new_n (Node t n l r) (Node t' n' l' r')
| t >= x && t >= t' = Node t new_n (merge x l r) (Node t' n' l' r')
| otherwise = Node t' new_n (Node t n l r) (merge x l' r')
where
new_n = 1 + n + n'


-- Returns the number of elements in a heap.
size :: Ord a => Heap a -> Int
size Empty = 0
size (Node _ n _ _) = n


-- Get the largest element in a non-empty heap.
-- Doesn't check for non-emptiness, therefore unsafe.
getMax :: Ord a => Heap a -> a
getMax (Node t _ _ _) = t


instance (Show a) => Show (Heap a) where
show tr = ((++) "n" . unlines . snd . toLines) tr

where

toLines :: (Show a) => Heap a -> (Int, [String])
toLines Empty = (0, [""])
toLines (Node t _ Empty Empty) = (0, [" " ++ show t])
toLines (Node t _ l r) = (ln + 1, lv_new ++ [" *"] ++ [" " ++ show t] ++ [" *"] ++ rv_new)
where
(il, lv) = toLines l
(ir, rv) = toLines r
ln = length lv
rn = length rv
lv_sub = (replicate il " ") ++ [" *******"] ++ (replicate (ln - il) " * ")
rv_sub = (replicate ir " * ") ++ [" *******"] ++ (replicate (rn - ir) " ")
lv_new = zipWith (++) lv_sub lv
rv_new = zipWith (++) rv_sub rv






haskell functional-programming heap immutability






share|improve this question









New contributor




Elmex80s is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Elmex80s is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 7 hours ago







Elmex80s













New contributor




Elmex80s is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 8 hours ago









Elmex80sElmex80s

1063




1063




New contributor




Elmex80s is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Elmex80s is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Elmex80s is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • $begingroup$
    Welcome to Code Review. Is there a specific reason why you don't want to use Maybe and therefore get partial functions? Also, is that Show instance intended?
    $endgroup$
    – Zeta
    6 hours ago




















  • $begingroup$
    Welcome to Code Review. Is there a specific reason why you don't want to use Maybe and therefore get partial functions? Also, is that Show instance intended?
    $endgroup$
    – Zeta
    6 hours ago


















$begingroup$
Welcome to Code Review. Is there a specific reason why you don't want to use Maybe and therefore get partial functions? Also, is that Show instance intended?
$endgroup$
– Zeta
6 hours ago






$begingroup$
Welcome to Code Review. Is there a specific reason why you don't want to use Maybe and therefore get partial functions? Also, is that Show instance intended?
$endgroup$
– Zeta
6 hours ago












0






active

oldest

votes











Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});






Elmex80s is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f211934%2fmax-heap-in-haskell%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes








Elmex80s is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















Elmex80s is a new contributor. Be nice, and check out our Code of Conduct.













Elmex80s is a new contributor. Be nice, and check out our Code of Conduct.












Elmex80s is a new contributor. Be nice, and check out our Code of Conduct.
















Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f211934%2fmax-heap-in-haskell%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

is 'sed' thread safe

How to make a Squid Proxy server?