Я следую за этим:
https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/10_Error_Handling#either-may-be-better-than-maybe
И я пытаюсь получить столбец данных из CSV по имени переменной в заголовках, заданная ранее часть здесь .
Вот мой код:
import Text.CSV
import Data.List
import Data.Maybe
dat <- parseCSVFromFile "/home/user/data.csv"
headers = head dat
records = tail dat
indexField :: [[Field]] -> Int -> [Field]
indexField records index = map (\x -> x !! index) records
, который работает:
Prelude> indexField records 0
[1,2,3]
И заголовки следующие:
Prelude> headers
["id", "category", "value"]
У меня есть следующее для индексации по полю имя вместо index
indexFieldbyName :: [[Field]] -> String -> [Field]
indexFieldbyName records indexName = indexField records (fromJust (elemIndex indexName headers))
Что также работает:
Prelude> indexFieldbyName records "id"
[1,2,3]
Однако, Я хочу, чтобы эта ошибка более информативна, когда ключ не найден в headers
:
Prelude> indexFieldbyName records "meow"
Maybe.fromJust: Nothing
Вот мои попытки:
indexFieldbyName2 :: [[Field]] -> String -> Either String [Field]
indexFieldbyName2 records indexName = indexField records index
where index = case (elemIndex indexName headers) of
Just v -> Right (v)
Nothing -> Left ("Index not found")
Parse error (line 31, column 5): parse error on input ‘Just’
И
indexFieldbyName3 :: [[Field]] -> String -> Either String [Field]
indexFieldbyName3 records indexName = indexField records index
where index = case v of
Just (elemIndex indexName headers) -> Right (v)
Nothing -> Left ("Index not found")
Parse error (line 44, column 4): parse error on input ‘Just’
indexFieldbyName4 :: [[Field]] -> String -> Either String [Field]
indexFieldbyName4 records indexName = indexField records index
where index = case v of
Just v -> Right (elemIndex indexName headers)
Nothing -> Left ("Index not found")
Parse error (line 37, column 4): parse error on input ‘Just’
Выше были проблемы с отступами, just
должен был быть справа от case
.Теперь у меня есть:
indexFieldbyName2' :: [[Field]] -> String -> Either String [Field]
indexFieldbyName2' records indexName = indexField records index
where index = case (elemIndex indexName headers) of
Just v -> Right (v)
Nothing -> Left ("Index not found")
<interactive>:4:39: error:
• Couldn't match expected type ‘Either String [Field]’ with actual type ‘[Field]’
• In the expression: indexField records index
In an equation for ‘indexFieldbyName2’:
indexFieldbyName2 records indexName
= indexField records index
where
index
= case (elemIndex indexName headers) of
Just v -> Right (v)
Nothing -> Left ("Index not found")
<interactive>:4:58: error:
• Couldn't match expected type ‘Int’ with actual type ‘Either String Int’
• In the second argument of ‘indexField’, namely ‘index’
In the expression: indexField records index
In an equation for ‘indexFieldbyName2’:
indexFieldbyName2 records indexName
= indexField records index
where
index
= case (elemIndex indexName headers) of
Just v -> Right (v)
Nothing -> Left ("Index not found")