How to deal with recursing through a list in Haskell (transpose operation)
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
While I understand that there may be transpose or ZipList functions in Haskell, I am trying to build my own transpose function that will take n lists of equal length m and transpose them into m lists of length n.
So far I have the function nearly working with the following code:
list = [[1,2,3],[4,5,6],[7,8,9]]
head' (x:xs) = x
head'' =
head'' (xs:lxs) = head' xs:head'' lxs
tail' =
tail' (x:xs) = xs
tail'' =
tail'' (xs:lxs) = tail' xs:tail'' lxs
merge (xs:lxs) = (head' xs:head'' lxs):(merge (tail' xs:tail'' lxs))
and I get the following output when I run > merge list
in ghci I get:
[[1,4,7],[2,5,8],[3,6,9],[*** Exception: list2.hs:16:1-16: Non-exhaustive patterns in function head'
which I am pretty sure means that the base case of the empty list on my head'
function is missing. The list is transposed, just not closed. How do I deal with that problem in this case? I have an inkling that it might have to do with Maybe
, but I'm having trouble implementing it that way.
list haskell recursion transpose non-exhaustive-patterns
add a comment |
While I understand that there may be transpose or ZipList functions in Haskell, I am trying to build my own transpose function that will take n lists of equal length m and transpose them into m lists of length n.
So far I have the function nearly working with the following code:
list = [[1,2,3],[4,5,6],[7,8,9]]
head' (x:xs) = x
head'' =
head'' (xs:lxs) = head' xs:head'' lxs
tail' =
tail' (x:xs) = xs
tail'' =
tail'' (xs:lxs) = tail' xs:tail'' lxs
merge (xs:lxs) = (head' xs:head'' lxs):(merge (tail' xs:tail'' lxs))
and I get the following output when I run > merge list
in ghci I get:
[[1,4,7],[2,5,8],[3,6,9],[*** Exception: list2.hs:16:1-16: Non-exhaustive patterns in function head'
which I am pretty sure means that the base case of the empty list on my head'
function is missing. The list is transposed, just not closed. How do I deal with that problem in this case? I have an inkling that it might have to do with Maybe
, but I'm having trouble implementing it that way.
list haskell recursion transpose non-exhaustive-patterns
6
head' (x:xs) = x
, but what ishead'
?
– Adam Smith
Jan 4 at 9:14
1
Sincehead' xs:head'' lxs = head'' (xs:lxs)
, you can collapsemerge (xs:lxs) = (head' xs:head'' lxs):...
tomerge (xs:lxs) = (head'' (xs:lxs)):...
. Similar equational reasoning applies to the...
, givingmerge (xs:lxs) = (head'' (xs:lxs)):(tail'' (xs:lxs))
. At that point there's not much point to pattern matching;merge lxs = head'' lxs:tail'' lxs
. But now you should definitely be suspicious: this definition ofmerge
obviously always calls(:)
and never. So how does one get to the "end" of the
merge
's output?
– Daniel Wagner
Jan 4 at 18:13
add a comment |
While I understand that there may be transpose or ZipList functions in Haskell, I am trying to build my own transpose function that will take n lists of equal length m and transpose them into m lists of length n.
So far I have the function nearly working with the following code:
list = [[1,2,3],[4,5,6],[7,8,9]]
head' (x:xs) = x
head'' =
head'' (xs:lxs) = head' xs:head'' lxs
tail' =
tail' (x:xs) = xs
tail'' =
tail'' (xs:lxs) = tail' xs:tail'' lxs
merge (xs:lxs) = (head' xs:head'' lxs):(merge (tail' xs:tail'' lxs))
and I get the following output when I run > merge list
in ghci I get:
[[1,4,7],[2,5,8],[3,6,9],[*** Exception: list2.hs:16:1-16: Non-exhaustive patterns in function head'
which I am pretty sure means that the base case of the empty list on my head'
function is missing. The list is transposed, just not closed. How do I deal with that problem in this case? I have an inkling that it might have to do with Maybe
, but I'm having trouble implementing it that way.
list haskell recursion transpose non-exhaustive-patterns
While I understand that there may be transpose or ZipList functions in Haskell, I am trying to build my own transpose function that will take n lists of equal length m and transpose them into m lists of length n.
So far I have the function nearly working with the following code:
list = [[1,2,3],[4,5,6],[7,8,9]]
head' (x:xs) = x
head'' =
head'' (xs:lxs) = head' xs:head'' lxs
tail' =
tail' (x:xs) = xs
tail'' =
tail'' (xs:lxs) = tail' xs:tail'' lxs
merge (xs:lxs) = (head' xs:head'' lxs):(merge (tail' xs:tail'' lxs))
and I get the following output when I run > merge list
in ghci I get:
[[1,4,7],[2,5,8],[3,6,9],[*** Exception: list2.hs:16:1-16: Non-exhaustive patterns in function head'
which I am pretty sure means that the base case of the empty list on my head'
function is missing. The list is transposed, just not closed. How do I deal with that problem in this case? I have an inkling that it might have to do with Maybe
, but I'm having trouble implementing it that way.
list haskell recursion transpose non-exhaustive-patterns
list haskell recursion transpose non-exhaustive-patterns
edited Jan 18 at 11:18
Will Ness
46.7k469127
46.7k469127
asked Jan 4 at 9:08
Ron FRon F
226
226
6
head' (x:xs) = x
, but what ishead'
?
– Adam Smith
Jan 4 at 9:14
1
Sincehead' xs:head'' lxs = head'' (xs:lxs)
, you can collapsemerge (xs:lxs) = (head' xs:head'' lxs):...
tomerge (xs:lxs) = (head'' (xs:lxs)):...
. Similar equational reasoning applies to the...
, givingmerge (xs:lxs) = (head'' (xs:lxs)):(tail'' (xs:lxs))
. At that point there's not much point to pattern matching;merge lxs = head'' lxs:tail'' lxs
. But now you should definitely be suspicious: this definition ofmerge
obviously always calls(:)
and never. So how does one get to the "end" of the
merge
's output?
– Daniel Wagner
Jan 4 at 18:13
add a comment |
6
head' (x:xs) = x
, but what ishead'
?
– Adam Smith
Jan 4 at 9:14
1
Sincehead' xs:head'' lxs = head'' (xs:lxs)
, you can collapsemerge (xs:lxs) = (head' xs:head'' lxs):...
tomerge (xs:lxs) = (head'' (xs:lxs)):...
. Similar equational reasoning applies to the...
, givingmerge (xs:lxs) = (head'' (xs:lxs)):(tail'' (xs:lxs))
. At that point there's not much point to pattern matching;merge lxs = head'' lxs:tail'' lxs
. But now you should definitely be suspicious: this definition ofmerge
obviously always calls(:)
and never. So how does one get to the "end" of the
merge
's output?
– Daniel Wagner
Jan 4 at 18:13
6
6
head' (x:xs) = x
, but what is head'
?– Adam Smith
Jan 4 at 9:14
head' (x:xs) = x
, but what is head'
?– Adam Smith
Jan 4 at 9:14
1
1
Since
head' xs:head'' lxs = head'' (xs:lxs)
, you can collapse merge (xs:lxs) = (head' xs:head'' lxs):...
to merge (xs:lxs) = (head'' (xs:lxs)):...
. Similar equational reasoning applies to the ...
, giving merge (xs:lxs) = (head'' (xs:lxs)):(tail'' (xs:lxs))
. At that point there's not much point to pattern matching; merge lxs = head'' lxs:tail'' lxs
. But now you should definitely be suspicious: this definition of merge
obviously always calls (:)
and never
. So how does one get to the "end" of the merge
's output?– Daniel Wagner
Jan 4 at 18:13
Since
head' xs:head'' lxs = head'' (xs:lxs)
, you can collapse merge (xs:lxs) = (head' xs:head'' lxs):...
to merge (xs:lxs) = (head'' (xs:lxs)):...
. Similar equational reasoning applies to the ...
, giving merge (xs:lxs) = (head'' (xs:lxs)):(tail'' (xs:lxs))
. At that point there's not much point to pattern matching; merge lxs = head'' lxs:tail'' lxs
. But now you should definitely be suspicious: this definition of merge
obviously always calls (:)
and never
. So how does one get to the "end" of the merge
's output?– Daniel Wagner
Jan 4 at 18:13
add a comment |
2 Answers
2
active
oldest
votes
You need to add exit conditions:
merge =
merge (:xss) = merge xss
So when doesmerge (:xss) = merge xss
run as opposed to the other two definitions ofmerge
?
– Ron F
Jan 4 at 18:24
add a comment |
map
is all you need, in addition to the existing head
and tail
functions. For simplicity, this assumes that the input is always a non-empty list (i.e., xs
might be [,,]
, but never alone, so there's no problem with using
head
or tail
.)
> map head list
[1,4,7]
> map tail list
[[2,3],[5,6],[8,9]]
> let foo xs = if null (head xs) then else map head xs : foo (map tail xs)
> foo list
[[1,4,7],[2,5,8],[3,6,9]]
add a comment |
Your Answer
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: "1"
};
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: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54035881%2fhow-to-deal-with-recursing-through-a-list-in-haskell-transpose-operation%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You need to add exit conditions:
merge =
merge (:xss) = merge xss
So when doesmerge (:xss) = merge xss
run as opposed to the other two definitions ofmerge
?
– Ron F
Jan 4 at 18:24
add a comment |
You need to add exit conditions:
merge =
merge (:xss) = merge xss
So when doesmerge (:xss) = merge xss
run as opposed to the other two definitions ofmerge
?
– Ron F
Jan 4 at 18:24
add a comment |
You need to add exit conditions:
merge =
merge (:xss) = merge xss
You need to add exit conditions:
merge =
merge (:xss) = merge xss
answered Jan 4 at 9:42
talextalex
11.9k11749
11.9k11749
So when doesmerge (:xss) = merge xss
run as opposed to the other two definitions ofmerge
?
– Ron F
Jan 4 at 18:24
add a comment |
So when doesmerge (:xss) = merge xss
run as opposed to the other two definitions ofmerge
?
– Ron F
Jan 4 at 18:24
So when does
merge (:xss) = merge xss
run as opposed to the other two definitions of merge
?– Ron F
Jan 4 at 18:24
So when does
merge (:xss) = merge xss
run as opposed to the other two definitions of merge
?– Ron F
Jan 4 at 18:24
add a comment |
map
is all you need, in addition to the existing head
and tail
functions. For simplicity, this assumes that the input is always a non-empty list (i.e., xs
might be [,,]
, but never alone, so there's no problem with using
head
or tail
.)
> map head list
[1,4,7]
> map tail list
[[2,3],[5,6],[8,9]]
> let foo xs = if null (head xs) then else map head xs : foo (map tail xs)
> foo list
[[1,4,7],[2,5,8],[3,6,9]]
add a comment |
map
is all you need, in addition to the existing head
and tail
functions. For simplicity, this assumes that the input is always a non-empty list (i.e., xs
might be [,,]
, but never alone, so there's no problem with using
head
or tail
.)
> map head list
[1,4,7]
> map tail list
[[2,3],[5,6],[8,9]]
> let foo xs = if null (head xs) then else map head xs : foo (map tail xs)
> foo list
[[1,4,7],[2,5,8],[3,6,9]]
add a comment |
map
is all you need, in addition to the existing head
and tail
functions. For simplicity, this assumes that the input is always a non-empty list (i.e., xs
might be [,,]
, but never alone, so there's no problem with using
head
or tail
.)
> map head list
[1,4,7]
> map tail list
[[2,3],[5,6],[8,9]]
> let foo xs = if null (head xs) then else map head xs : foo (map tail xs)
> foo list
[[1,4,7],[2,5,8],[3,6,9]]
map
is all you need, in addition to the existing head
and tail
functions. For simplicity, this assumes that the input is always a non-empty list (i.e., xs
might be [,,]
, but never alone, so there's no problem with using
head
or tail
.)
> map head list
[1,4,7]
> map tail list
[[2,3],[5,6],[8,9]]
> let foo xs = if null (head xs) then else map head xs : foo (map tail xs)
> foo list
[[1,4,7],[2,5,8],[3,6,9]]
answered Jan 4 at 14:14
chepnerchepner
262k36251345
262k36251345
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- 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.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54035881%2fhow-to-deal-with-recursing-through-a-list-in-haskell-transpose-operation%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
6
head' (x:xs) = x
, but what ishead'
?– Adam Smith
Jan 4 at 9:14
1
Since
head' xs:head'' lxs = head'' (xs:lxs)
, you can collapsemerge (xs:lxs) = (head' xs:head'' lxs):...
tomerge (xs:lxs) = (head'' (xs:lxs)):...
. Similar equational reasoning applies to the...
, givingmerge (xs:lxs) = (head'' (xs:lxs)):(tail'' (xs:lxs))
. At that point there's not much point to pattern matching;merge lxs = head'' lxs:tail'' lxs
. But now you should definitely be suspicious: this definition ofmerge
obviously always calls(:)
and never. So how does one get to the "end" of the
merge
's output?– Daniel Wagner
Jan 4 at 18:13