When to use Eq in Haskell type declarations?
It is my understanding that you should add Eq ...
to a functions' type declaration when you use ==
or =
to compare one of the functions parameters. However, GHCi says that the following also requires an Eq
type class:
take' _ =
take' 0 _ =
take' n (x:xs) = x : take' (n - 1) xs
%% Needs the following type class
%% take' :: (Eq t, Num t) => t -> [a] -> [a]
Why does it require Eq t
to be added to the type declaration, even though the n
parameter is never compared with anything?
haskell
add a comment |
It is my understanding that you should add Eq ...
to a functions' type declaration when you use ==
or =
to compare one of the functions parameters. However, GHCi says that the following also requires an Eq
type class:
take' _ =
take' 0 _ =
take' n (x:xs) = x : take' (n - 1) xs
%% Needs the following type class
%% take' :: (Eq t, Num t) => t -> [a] -> [a]
Why does it require Eq t
to be added to the type declaration, even though the n
parameter is never compared with anything?
haskell
add a comment |
It is my understanding that you should add Eq ...
to a functions' type declaration when you use ==
or =
to compare one of the functions parameters. However, GHCi says that the following also requires an Eq
type class:
take' _ =
take' 0 _ =
take' n (x:xs) = x : take' (n - 1) xs
%% Needs the following type class
%% take' :: (Eq t, Num t) => t -> [a] -> [a]
Why does it require Eq t
to be added to the type declaration, even though the n
parameter is never compared with anything?
haskell
It is my understanding that you should add Eq ...
to a functions' type declaration when you use ==
or =
to compare one of the functions parameters. However, GHCi says that the following also requires an Eq
type class:
take' _ =
take' 0 _ =
take' n (x:xs) = x : take' (n - 1) xs
%% Needs the following type class
%% take' :: (Eq t, Num t) => t -> [a] -> [a]
Why does it require Eq t
to be added to the type declaration, even though the n
parameter is never compared with anything?
haskell
haskell
asked Dec 28 '18 at 23:22
LaaLaa
1226
1226
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
The pattern match take' 0 _ = ...
is syntactic sugar for an equality check, namely
take' _ =
take' n _
| n==0 =
take' n (x:xs) = x : take' (n - 1) xs
So this requires Eq t
if you want the counter-argument to be polymorphic t
. Also Num t
so you can have the value 0
and to calculate n-1
.
Practically speaking, there's not much compelling reason to use take
with any type but Int
, so the standard version just isn't polymorphic at all in that argument:
take :: Int -> [a] -> [a]
with Int
being known as an instance of both Eq
and Num
.
That make sense, thank you. Wouldn'ttake
still be polymorphic with typetake :: Int -> [a] -> [a]
, because the lists can be of any type?
– Laa
Dec 28 '18 at 23:33
2
Yeah, but not polymorphic in the number type.
– leftaroundabout
Dec 28 '18 at 23:35
Could I also ask whyNum t
is neccesary, instead of sayIntergral t
? Because the function wouldn't work if you were to pass a float / double into it anyway. Is it simply because Haskell isn't able to recognize that it wouldn't work with a float / double?
– Laa
Dec 28 '18 at 23:39
3
Well, it would work withFloat
, just it would behave stupid for non-integral ones – but the compiler doesn't know what's stupid. What if you wanted the function to just keep on going if the argument is fractional and flips over to negative in the recursion? You're right, this doesn't make sense and if you make it number-polymorphic you should requireIntegral
. But as I said, even better you should just use a concrete number type likeInt
(or, to be completely type-sound,Natural
).
– leftaroundabout
Dec 28 '18 at 23:43
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%2f53965343%2fwhen-to-use-eq-in-haskell-type-declarations%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The pattern match take' 0 _ = ...
is syntactic sugar for an equality check, namely
take' _ =
take' n _
| n==0 =
take' n (x:xs) = x : take' (n - 1) xs
So this requires Eq t
if you want the counter-argument to be polymorphic t
. Also Num t
so you can have the value 0
and to calculate n-1
.
Practically speaking, there's not much compelling reason to use take
with any type but Int
, so the standard version just isn't polymorphic at all in that argument:
take :: Int -> [a] -> [a]
with Int
being known as an instance of both Eq
and Num
.
That make sense, thank you. Wouldn'ttake
still be polymorphic with typetake :: Int -> [a] -> [a]
, because the lists can be of any type?
– Laa
Dec 28 '18 at 23:33
2
Yeah, but not polymorphic in the number type.
– leftaroundabout
Dec 28 '18 at 23:35
Could I also ask whyNum t
is neccesary, instead of sayIntergral t
? Because the function wouldn't work if you were to pass a float / double into it anyway. Is it simply because Haskell isn't able to recognize that it wouldn't work with a float / double?
– Laa
Dec 28 '18 at 23:39
3
Well, it would work withFloat
, just it would behave stupid for non-integral ones – but the compiler doesn't know what's stupid. What if you wanted the function to just keep on going if the argument is fractional and flips over to negative in the recursion? You're right, this doesn't make sense and if you make it number-polymorphic you should requireIntegral
. But as I said, even better you should just use a concrete number type likeInt
(or, to be completely type-sound,Natural
).
– leftaroundabout
Dec 28 '18 at 23:43
add a comment |
The pattern match take' 0 _ = ...
is syntactic sugar for an equality check, namely
take' _ =
take' n _
| n==0 =
take' n (x:xs) = x : take' (n - 1) xs
So this requires Eq t
if you want the counter-argument to be polymorphic t
. Also Num t
so you can have the value 0
and to calculate n-1
.
Practically speaking, there's not much compelling reason to use take
with any type but Int
, so the standard version just isn't polymorphic at all in that argument:
take :: Int -> [a] -> [a]
with Int
being known as an instance of both Eq
and Num
.
That make sense, thank you. Wouldn'ttake
still be polymorphic with typetake :: Int -> [a] -> [a]
, because the lists can be of any type?
– Laa
Dec 28 '18 at 23:33
2
Yeah, but not polymorphic in the number type.
– leftaroundabout
Dec 28 '18 at 23:35
Could I also ask whyNum t
is neccesary, instead of sayIntergral t
? Because the function wouldn't work if you were to pass a float / double into it anyway. Is it simply because Haskell isn't able to recognize that it wouldn't work with a float / double?
– Laa
Dec 28 '18 at 23:39
3
Well, it would work withFloat
, just it would behave stupid for non-integral ones – but the compiler doesn't know what's stupid. What if you wanted the function to just keep on going if the argument is fractional and flips over to negative in the recursion? You're right, this doesn't make sense and if you make it number-polymorphic you should requireIntegral
. But as I said, even better you should just use a concrete number type likeInt
(or, to be completely type-sound,Natural
).
– leftaroundabout
Dec 28 '18 at 23:43
add a comment |
The pattern match take' 0 _ = ...
is syntactic sugar for an equality check, namely
take' _ =
take' n _
| n==0 =
take' n (x:xs) = x : take' (n - 1) xs
So this requires Eq t
if you want the counter-argument to be polymorphic t
. Also Num t
so you can have the value 0
and to calculate n-1
.
Practically speaking, there's not much compelling reason to use take
with any type but Int
, so the standard version just isn't polymorphic at all in that argument:
take :: Int -> [a] -> [a]
with Int
being known as an instance of both Eq
and Num
.
The pattern match take' 0 _ = ...
is syntactic sugar for an equality check, namely
take' _ =
take' n _
| n==0 =
take' n (x:xs) = x : take' (n - 1) xs
So this requires Eq t
if you want the counter-argument to be polymorphic t
. Also Num t
so you can have the value 0
and to calculate n-1
.
Practically speaking, there's not much compelling reason to use take
with any type but Int
, so the standard version just isn't polymorphic at all in that argument:
take :: Int -> [a] -> [a]
with Int
being known as an instance of both Eq
and Num
.
answered Dec 28 '18 at 23:28
leftaroundaboutleftaroundabout
79.3k3117233
79.3k3117233
That make sense, thank you. Wouldn'ttake
still be polymorphic with typetake :: Int -> [a] -> [a]
, because the lists can be of any type?
– Laa
Dec 28 '18 at 23:33
2
Yeah, but not polymorphic in the number type.
– leftaroundabout
Dec 28 '18 at 23:35
Could I also ask whyNum t
is neccesary, instead of sayIntergral t
? Because the function wouldn't work if you were to pass a float / double into it anyway. Is it simply because Haskell isn't able to recognize that it wouldn't work with a float / double?
– Laa
Dec 28 '18 at 23:39
3
Well, it would work withFloat
, just it would behave stupid for non-integral ones – but the compiler doesn't know what's stupid. What if you wanted the function to just keep on going if the argument is fractional and flips over to negative in the recursion? You're right, this doesn't make sense and if you make it number-polymorphic you should requireIntegral
. But as I said, even better you should just use a concrete number type likeInt
(or, to be completely type-sound,Natural
).
– leftaroundabout
Dec 28 '18 at 23:43
add a comment |
That make sense, thank you. Wouldn'ttake
still be polymorphic with typetake :: Int -> [a] -> [a]
, because the lists can be of any type?
– Laa
Dec 28 '18 at 23:33
2
Yeah, but not polymorphic in the number type.
– leftaroundabout
Dec 28 '18 at 23:35
Could I also ask whyNum t
is neccesary, instead of sayIntergral t
? Because the function wouldn't work if you were to pass a float / double into it anyway. Is it simply because Haskell isn't able to recognize that it wouldn't work with a float / double?
– Laa
Dec 28 '18 at 23:39
3
Well, it would work withFloat
, just it would behave stupid for non-integral ones – but the compiler doesn't know what's stupid. What if you wanted the function to just keep on going if the argument is fractional and flips over to negative in the recursion? You're right, this doesn't make sense and if you make it number-polymorphic you should requireIntegral
. But as I said, even better you should just use a concrete number type likeInt
(or, to be completely type-sound,Natural
).
– leftaroundabout
Dec 28 '18 at 23:43
That make sense, thank you. Wouldn't
take
still be polymorphic with type take :: Int -> [a] -> [a]
, because the lists can be of any type?– Laa
Dec 28 '18 at 23:33
That make sense, thank you. Wouldn't
take
still be polymorphic with type take :: Int -> [a] -> [a]
, because the lists can be of any type?– Laa
Dec 28 '18 at 23:33
2
2
Yeah, but not polymorphic in the number type.
– leftaroundabout
Dec 28 '18 at 23:35
Yeah, but not polymorphic in the number type.
– leftaroundabout
Dec 28 '18 at 23:35
Could I also ask why
Num t
is neccesary, instead of say Intergral t
? Because the function wouldn't work if you were to pass a float / double into it anyway. Is it simply because Haskell isn't able to recognize that it wouldn't work with a float / double?– Laa
Dec 28 '18 at 23:39
Could I also ask why
Num t
is neccesary, instead of say Intergral t
? Because the function wouldn't work if you were to pass a float / double into it anyway. Is it simply because Haskell isn't able to recognize that it wouldn't work with a float / double?– Laa
Dec 28 '18 at 23:39
3
3
Well, it would work with
Float
, just it would behave stupid for non-integral ones – but the compiler doesn't know what's stupid. What if you wanted the function to just keep on going if the argument is fractional and flips over to negative in the recursion? You're right, this doesn't make sense and if you make it number-polymorphic you should require Integral
. But as I said, even better you should just use a concrete number type like Int
(or, to be completely type-sound, Natural
).– leftaroundabout
Dec 28 '18 at 23:43
Well, it would work with
Float
, just it would behave stupid for non-integral ones – but the compiler doesn't know what's stupid. What if you wanted the function to just keep on going if the argument is fractional and flips over to negative in the recursion? You're right, this doesn't make sense and if you make it number-polymorphic you should require Integral
. But as I said, even better you should just use a concrete number type like Int
(or, to be completely type-sound, Natural
).– leftaroundabout
Dec 28 '18 at 23:43
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%2f53965343%2fwhen-to-use-eq-in-haskell-type-declarations%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