Get Column in Haskell CSV and infer the column type
I'm exploring a csv file in an interactive ghci session (in a jupyter notebook):
import Text.CSV
import Data.List
import Data.Maybe
dat <- parseCSVFromFile "/home/user/data.csv"
headers = head dat
records = tail dat
-- define a way to get a particular row by index
indexRow :: [[Field]] -> Int -> [Field]
indexRow csv index = csv !! index
indexRow records 1
-- this works!
-- Now, define a way to get a particular column by index
indexField :: [[Field]] -> Int -> [Field]
indexField records index = map (x -> x !! index) records
While this works if I know in advance the type of column 3:
map (x -> read x :: Double) $ indexField records 3
How can I ask read
to infer what the type might be when for example my columns could contain strings or num? I'd like it to try for me, but:
map read $ indexField records 3
fails with
Prelude.read: no parse
I don't care whether they are string or num, I just need that they are all the same and I am failing to find a way to specify that generally with the read function at least.
Weirdly, if I define a mean function like so:
mean :: Fractional a => [a] -> Maybe a
mean = Nothing
mean [x] = Just x
mean xs = Just (sum(xs) / (fromIntegral (length xs)))
This works:
mean $ map read $ indexField records 2
Just 13.501359655240003
But without the mean, this still fails:
map read $ indexField records 2
Prelude.read: no parse
csv haskell
add a comment |
I'm exploring a csv file in an interactive ghci session (in a jupyter notebook):
import Text.CSV
import Data.List
import Data.Maybe
dat <- parseCSVFromFile "/home/user/data.csv"
headers = head dat
records = tail dat
-- define a way to get a particular row by index
indexRow :: [[Field]] -> Int -> [Field]
indexRow csv index = csv !! index
indexRow records 1
-- this works!
-- Now, define a way to get a particular column by index
indexField :: [[Field]] -> Int -> [Field]
indexField records index = map (x -> x !! index) records
While this works if I know in advance the type of column 3:
map (x -> read x :: Double) $ indexField records 3
How can I ask read
to infer what the type might be when for example my columns could contain strings or num? I'd like it to try for me, but:
map read $ indexField records 3
fails with
Prelude.read: no parse
I don't care whether they are string or num, I just need that they are all the same and I am failing to find a way to specify that generally with the read function at least.
Weirdly, if I define a mean function like so:
mean :: Fractional a => [a] -> Maybe a
mean = Nothing
mean [x] = Just x
mean xs = Just (sum(xs) / (fromIntegral (length xs)))
This works:
mean $ map read $ indexField records 2
Just 13.501359655240003
But without the mean, this still fails:
map read $ indexField records 2
Prelude.read: no parse
csv haskell
try(map read $ indexField records 2)::(Read a, Fractional a)=>[a]
. Moreover, if your columns could contain strings or num, you cannot put them in list, since the element of list must be same type.
– assembly.jc
Dec 28 '18 at 10:21
@assembly.jc, I expect data to be consistent within a column, so there won't be mixed types, but I do expect each column may be different from each other column--column 1 is integers, columns 2 is doubles, column 3 is strings, etc. (Or if there is a mix within a column, you'd have to infer a list of strings.)
– Mittenchops
Dec 28 '18 at 10:35
@Zeta this is noted.
– Mittenchops
Dec 28 '18 at 10:36
Even though the data type is consistent within a column, you still need to specify the type forread
, or it can be inferred from context, for example:sum $ map read $ indexField records 2
, compiler know you want numeric type and try to pick one of numeric type for you, in above example, it will tryInteger
.
– assembly.jc
Dec 28 '18 at 11:22
add a comment |
I'm exploring a csv file in an interactive ghci session (in a jupyter notebook):
import Text.CSV
import Data.List
import Data.Maybe
dat <- parseCSVFromFile "/home/user/data.csv"
headers = head dat
records = tail dat
-- define a way to get a particular row by index
indexRow :: [[Field]] -> Int -> [Field]
indexRow csv index = csv !! index
indexRow records 1
-- this works!
-- Now, define a way to get a particular column by index
indexField :: [[Field]] -> Int -> [Field]
indexField records index = map (x -> x !! index) records
While this works if I know in advance the type of column 3:
map (x -> read x :: Double) $ indexField records 3
How can I ask read
to infer what the type might be when for example my columns could contain strings or num? I'd like it to try for me, but:
map read $ indexField records 3
fails with
Prelude.read: no parse
I don't care whether they are string or num, I just need that they are all the same and I am failing to find a way to specify that generally with the read function at least.
Weirdly, if I define a mean function like so:
mean :: Fractional a => [a] -> Maybe a
mean = Nothing
mean [x] = Just x
mean xs = Just (sum(xs) / (fromIntegral (length xs)))
This works:
mean $ map read $ indexField records 2
Just 13.501359655240003
But without the mean, this still fails:
map read $ indexField records 2
Prelude.read: no parse
csv haskell
I'm exploring a csv file in an interactive ghci session (in a jupyter notebook):
import Text.CSV
import Data.List
import Data.Maybe
dat <- parseCSVFromFile "/home/user/data.csv"
headers = head dat
records = tail dat
-- define a way to get a particular row by index
indexRow :: [[Field]] -> Int -> [Field]
indexRow csv index = csv !! index
indexRow records 1
-- this works!
-- Now, define a way to get a particular column by index
indexField :: [[Field]] -> Int -> [Field]
indexField records index = map (x -> x !! index) records
While this works if I know in advance the type of column 3:
map (x -> read x :: Double) $ indexField records 3
How can I ask read
to infer what the type might be when for example my columns could contain strings or num? I'd like it to try for me, but:
map read $ indexField records 3
fails with
Prelude.read: no parse
I don't care whether they are string or num, I just need that they are all the same and I am failing to find a way to specify that generally with the read function at least.
Weirdly, if I define a mean function like so:
mean :: Fractional a => [a] -> Maybe a
mean = Nothing
mean [x] = Just x
mean xs = Just (sum(xs) / (fromIntegral (length xs)))
This works:
mean $ map read $ indexField records 2
Just 13.501359655240003
But without the mean, this still fails:
map read $ indexField records 2
Prelude.read: no parse
csv haskell
csv haskell
edited Dec 28 '18 at 10:36
Mittenchops
asked Dec 28 '18 at 9:43
MittenchopsMittenchops
6,4042165137
6,4042165137
try(map read $ indexField records 2)::(Read a, Fractional a)=>[a]
. Moreover, if your columns could contain strings or num, you cannot put them in list, since the element of list must be same type.
– assembly.jc
Dec 28 '18 at 10:21
@assembly.jc, I expect data to be consistent within a column, so there won't be mixed types, but I do expect each column may be different from each other column--column 1 is integers, columns 2 is doubles, column 3 is strings, etc. (Or if there is a mix within a column, you'd have to infer a list of strings.)
– Mittenchops
Dec 28 '18 at 10:35
@Zeta this is noted.
– Mittenchops
Dec 28 '18 at 10:36
Even though the data type is consistent within a column, you still need to specify the type forread
, or it can be inferred from context, for example:sum $ map read $ indexField records 2
, compiler know you want numeric type and try to pick one of numeric type for you, in above example, it will tryInteger
.
– assembly.jc
Dec 28 '18 at 11:22
add a comment |
try(map read $ indexField records 2)::(Read a, Fractional a)=>[a]
. Moreover, if your columns could contain strings or num, you cannot put them in list, since the element of list must be same type.
– assembly.jc
Dec 28 '18 at 10:21
@assembly.jc, I expect data to be consistent within a column, so there won't be mixed types, but I do expect each column may be different from each other column--column 1 is integers, columns 2 is doubles, column 3 is strings, etc. (Or if there is a mix within a column, you'd have to infer a list of strings.)
– Mittenchops
Dec 28 '18 at 10:35
@Zeta this is noted.
– Mittenchops
Dec 28 '18 at 10:36
Even though the data type is consistent within a column, you still need to specify the type forread
, or it can be inferred from context, for example:sum $ map read $ indexField records 2
, compiler know you want numeric type and try to pick one of numeric type for you, in above example, it will tryInteger
.
– assembly.jc
Dec 28 '18 at 11:22
try
(map read $ indexField records 2)::(Read a, Fractional a)=>[a]
. Moreover, if your columns could contain strings or num, you cannot put them in list, since the element of list must be same type.– assembly.jc
Dec 28 '18 at 10:21
try
(map read $ indexField records 2)::(Read a, Fractional a)=>[a]
. Moreover, if your columns could contain strings or num, you cannot put them in list, since the element of list must be same type.– assembly.jc
Dec 28 '18 at 10:21
@assembly.jc, I expect data to be consistent within a column, so there won't be mixed types, but I do expect each column may be different from each other column--column 1 is integers, columns 2 is doubles, column 3 is strings, etc. (Or if there is a mix within a column, you'd have to infer a list of strings.)
– Mittenchops
Dec 28 '18 at 10:35
@assembly.jc, I expect data to be consistent within a column, so there won't be mixed types, but I do expect each column may be different from each other column--column 1 is integers, columns 2 is doubles, column 3 is strings, etc. (Or if there is a mix within a column, you'd have to infer a list of strings.)
– Mittenchops
Dec 28 '18 at 10:35
@Zeta this is noted.
– Mittenchops
Dec 28 '18 at 10:36
@Zeta this is noted.
– Mittenchops
Dec 28 '18 at 10:36
Even though the data type is consistent within a column, you still need to specify the type for
read
, or it can be inferred from context, for example: sum $ map read $ indexField records 2
, compiler know you want numeric type and try to pick one of numeric type for you, in above example, it will try Integer
.– assembly.jc
Dec 28 '18 at 11:22
Even though the data type is consistent within a column, you still need to specify the type for
read
, or it can be inferred from context, for example: sum $ map read $ indexField records 2
, compiler know you want numeric type and try to pick one of numeric type for you, in above example, it will try Integer
.– assembly.jc
Dec 28 '18 at 11:22
add a comment |
1 Answer
1
active
oldest
votes
Unfortunately, read
is at the end of its wits when it comes to situations like this. Let's revisit read
:
read :: Read a => String -> a
As you can see, a
doesn't depend on the input, but solely on the output, and therefore of the context of our function. If you use read a + read b
, then the additional Num
context will limit the types to Integer
or Double
due to default
rules. Let's see it in action:
> :set +t
> read "1234"
*** Exception: Prelude.read: no parse
> read "1234" + read "1234"
2468
it :: (Num a, Read a) => a
Ok, a
is still not helpful. Is there any type that we can read without additional context? Sure, unit:
> read "()"
()
it :: Read a => a
That's still not helpful at all, so let's enable the monomorphism restriction:
> :set -XMonomorphismRestriction
> read "1234" + read "1234"
2468
it :: Integer
Aha. In the end, we had an Integer
. Due to +
, we had to decide on a type. Now, with the MonomorphismRestriction
enabled, what happens on read "1234"
without additional context?
> read "1234"
<interactive>:20:1
No instance for (Read a0) arising from a use of 'read'
The type variable 'a0' is ambiguous
Now GHCi doesn't pick any (default) type and forces you to chose one. Which makes the underlying error much more clear.
So how do we fix this? As CSV can contain arbitrary fields at run-time and all types are determined statically, we have to cheat by introducing something like
data CSVField = CSVString String | CSVNumber Double | CSVUnknown
and then write
parse :: Field -> CSVField
After all, our type needs to cover all possible fields.
However, in your case, we can just restrict read's
type:
myRead :: String -> Double
myRead = read
But that's not wise, as we can still end up with errors if the column doesn't contain Double
s to begin with. So instead, let's use readMaybe
and mapM
:
columnAsNumbers :: [Field] -> Maybe [Double]
columnAsNumbers = mapM readMaybe
That way, the type is fixed, and we're forced to check whether we have Just
something or Nothing
:
mean <$> columnAsNumbers (indexFields records 2)
If you find yourself often using columnAsNumbers
create an operator, though:
(!!$) :: [[Field]] -> Maybe [Double]
records !!$ index = columnAsNumbers $ indexFields records index
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%2f53956462%2fget-column-in-haskell-csv-and-infer-the-column-type%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
Unfortunately, read
is at the end of its wits when it comes to situations like this. Let's revisit read
:
read :: Read a => String -> a
As you can see, a
doesn't depend on the input, but solely on the output, and therefore of the context of our function. If you use read a + read b
, then the additional Num
context will limit the types to Integer
or Double
due to default
rules. Let's see it in action:
> :set +t
> read "1234"
*** Exception: Prelude.read: no parse
> read "1234" + read "1234"
2468
it :: (Num a, Read a) => a
Ok, a
is still not helpful. Is there any type that we can read without additional context? Sure, unit:
> read "()"
()
it :: Read a => a
That's still not helpful at all, so let's enable the monomorphism restriction:
> :set -XMonomorphismRestriction
> read "1234" + read "1234"
2468
it :: Integer
Aha. In the end, we had an Integer
. Due to +
, we had to decide on a type. Now, with the MonomorphismRestriction
enabled, what happens on read "1234"
without additional context?
> read "1234"
<interactive>:20:1
No instance for (Read a0) arising from a use of 'read'
The type variable 'a0' is ambiguous
Now GHCi doesn't pick any (default) type and forces you to chose one. Which makes the underlying error much more clear.
So how do we fix this? As CSV can contain arbitrary fields at run-time and all types are determined statically, we have to cheat by introducing something like
data CSVField = CSVString String | CSVNumber Double | CSVUnknown
and then write
parse :: Field -> CSVField
After all, our type needs to cover all possible fields.
However, in your case, we can just restrict read's
type:
myRead :: String -> Double
myRead = read
But that's not wise, as we can still end up with errors if the column doesn't contain Double
s to begin with. So instead, let's use readMaybe
and mapM
:
columnAsNumbers :: [Field] -> Maybe [Double]
columnAsNumbers = mapM readMaybe
That way, the type is fixed, and we're forced to check whether we have Just
something or Nothing
:
mean <$> columnAsNumbers (indexFields records 2)
If you find yourself often using columnAsNumbers
create an operator, though:
(!!$) :: [[Field]] -> Maybe [Double]
records !!$ index = columnAsNumbers $ indexFields records index
add a comment |
Unfortunately, read
is at the end of its wits when it comes to situations like this. Let's revisit read
:
read :: Read a => String -> a
As you can see, a
doesn't depend on the input, but solely on the output, and therefore of the context of our function. If you use read a + read b
, then the additional Num
context will limit the types to Integer
or Double
due to default
rules. Let's see it in action:
> :set +t
> read "1234"
*** Exception: Prelude.read: no parse
> read "1234" + read "1234"
2468
it :: (Num a, Read a) => a
Ok, a
is still not helpful. Is there any type that we can read without additional context? Sure, unit:
> read "()"
()
it :: Read a => a
That's still not helpful at all, so let's enable the monomorphism restriction:
> :set -XMonomorphismRestriction
> read "1234" + read "1234"
2468
it :: Integer
Aha. In the end, we had an Integer
. Due to +
, we had to decide on a type. Now, with the MonomorphismRestriction
enabled, what happens on read "1234"
without additional context?
> read "1234"
<interactive>:20:1
No instance for (Read a0) arising from a use of 'read'
The type variable 'a0' is ambiguous
Now GHCi doesn't pick any (default) type and forces you to chose one. Which makes the underlying error much more clear.
So how do we fix this? As CSV can contain arbitrary fields at run-time and all types are determined statically, we have to cheat by introducing something like
data CSVField = CSVString String | CSVNumber Double | CSVUnknown
and then write
parse :: Field -> CSVField
After all, our type needs to cover all possible fields.
However, in your case, we can just restrict read's
type:
myRead :: String -> Double
myRead = read
But that's not wise, as we can still end up with errors if the column doesn't contain Double
s to begin with. So instead, let's use readMaybe
and mapM
:
columnAsNumbers :: [Field] -> Maybe [Double]
columnAsNumbers = mapM readMaybe
That way, the type is fixed, and we're forced to check whether we have Just
something or Nothing
:
mean <$> columnAsNumbers (indexFields records 2)
If you find yourself often using columnAsNumbers
create an operator, though:
(!!$) :: [[Field]] -> Maybe [Double]
records !!$ index = columnAsNumbers $ indexFields records index
add a comment |
Unfortunately, read
is at the end of its wits when it comes to situations like this. Let's revisit read
:
read :: Read a => String -> a
As you can see, a
doesn't depend on the input, but solely on the output, and therefore of the context of our function. If you use read a + read b
, then the additional Num
context will limit the types to Integer
or Double
due to default
rules. Let's see it in action:
> :set +t
> read "1234"
*** Exception: Prelude.read: no parse
> read "1234" + read "1234"
2468
it :: (Num a, Read a) => a
Ok, a
is still not helpful. Is there any type that we can read without additional context? Sure, unit:
> read "()"
()
it :: Read a => a
That's still not helpful at all, so let's enable the monomorphism restriction:
> :set -XMonomorphismRestriction
> read "1234" + read "1234"
2468
it :: Integer
Aha. In the end, we had an Integer
. Due to +
, we had to decide on a type. Now, with the MonomorphismRestriction
enabled, what happens on read "1234"
without additional context?
> read "1234"
<interactive>:20:1
No instance for (Read a0) arising from a use of 'read'
The type variable 'a0' is ambiguous
Now GHCi doesn't pick any (default) type and forces you to chose one. Which makes the underlying error much more clear.
So how do we fix this? As CSV can contain arbitrary fields at run-time and all types are determined statically, we have to cheat by introducing something like
data CSVField = CSVString String | CSVNumber Double | CSVUnknown
and then write
parse :: Field -> CSVField
After all, our type needs to cover all possible fields.
However, in your case, we can just restrict read's
type:
myRead :: String -> Double
myRead = read
But that's not wise, as we can still end up with errors if the column doesn't contain Double
s to begin with. So instead, let's use readMaybe
and mapM
:
columnAsNumbers :: [Field] -> Maybe [Double]
columnAsNumbers = mapM readMaybe
That way, the type is fixed, and we're forced to check whether we have Just
something or Nothing
:
mean <$> columnAsNumbers (indexFields records 2)
If you find yourself often using columnAsNumbers
create an operator, though:
(!!$) :: [[Field]] -> Maybe [Double]
records !!$ index = columnAsNumbers $ indexFields records index
Unfortunately, read
is at the end of its wits when it comes to situations like this. Let's revisit read
:
read :: Read a => String -> a
As you can see, a
doesn't depend on the input, but solely on the output, and therefore of the context of our function. If you use read a + read b
, then the additional Num
context will limit the types to Integer
or Double
due to default
rules. Let's see it in action:
> :set +t
> read "1234"
*** Exception: Prelude.read: no parse
> read "1234" + read "1234"
2468
it :: (Num a, Read a) => a
Ok, a
is still not helpful. Is there any type that we can read without additional context? Sure, unit:
> read "()"
()
it :: Read a => a
That's still not helpful at all, so let's enable the monomorphism restriction:
> :set -XMonomorphismRestriction
> read "1234" + read "1234"
2468
it :: Integer
Aha. In the end, we had an Integer
. Due to +
, we had to decide on a type. Now, with the MonomorphismRestriction
enabled, what happens on read "1234"
without additional context?
> read "1234"
<interactive>:20:1
No instance for (Read a0) arising from a use of 'read'
The type variable 'a0' is ambiguous
Now GHCi doesn't pick any (default) type and forces you to chose one. Which makes the underlying error much more clear.
So how do we fix this? As CSV can contain arbitrary fields at run-time and all types are determined statically, we have to cheat by introducing something like
data CSVField = CSVString String | CSVNumber Double | CSVUnknown
and then write
parse :: Field -> CSVField
After all, our type needs to cover all possible fields.
However, in your case, we can just restrict read's
type:
myRead :: String -> Double
myRead = read
But that's not wise, as we can still end up with errors if the column doesn't contain Double
s to begin with. So instead, let's use readMaybe
and mapM
:
columnAsNumbers :: [Field] -> Maybe [Double]
columnAsNumbers = mapM readMaybe
That way, the type is fixed, and we're forced to check whether we have Just
something or Nothing
:
mean <$> columnAsNumbers (indexFields records 2)
If you find yourself often using columnAsNumbers
create an operator, though:
(!!$) :: [[Field]] -> Maybe [Double]
records !!$ index = columnAsNumbers $ indexFields records index
answered Dec 28 '18 at 10:37
ZetaZeta
81.5k11134185
81.5k11134185
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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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%2f53956462%2fget-column-in-haskell-csv-and-infer-the-column-type%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
try
(map read $ indexField records 2)::(Read a, Fractional a)=>[a]
. Moreover, if your columns could contain strings or num, you cannot put them in list, since the element of list must be same type.– assembly.jc
Dec 28 '18 at 10:21
@assembly.jc, I expect data to be consistent within a column, so there won't be mixed types, but I do expect each column may be different from each other column--column 1 is integers, columns 2 is doubles, column 3 is strings, etc. (Or if there is a mix within a column, you'd have to infer a list of strings.)
– Mittenchops
Dec 28 '18 at 10:35
@Zeta this is noted.
– Mittenchops
Dec 28 '18 at 10:36
Even though the data type is consistent within a column, you still need to specify the type for
read
, or it can be inferred from context, for example:sum $ map read $ indexField records 2
, compiler know you want numeric type and try to pick one of numeric type for you, in above example, it will tryInteger
.– assembly.jc
Dec 28 '18 at 11:22