создание моего собственного модуля и типов работает не так, как ожидалось

#list #haskell #types #module #tuples

#Список #haskell #типы #модуль #кортежи

Вопрос:

Я пытаюсь создать программу на haskell с модулями и создать свои собственные типы для имитации выборов: пока у меня есть это:

 module Election
( nactionCreate
,  getState
, addVotesToState
, nactionAddVotes
, stateWinner
, electionWinner
) where

-- Types Created
data Candidate = A | B deriving (Eq, Show)

type State = (String, Int, Int, Int) --deriving (Eq, Show, Read)

name :: State -> String
name (name, _, _, _) = name

representativesNumber :: state -> Int
representativesNumber (_, representativesNumber, _, _,) = representativesNumber

aVotes :: State -> Int
aVotes (_, _, aVotes, _) = aVotes

bVotes :: State -> Int
bVotes (_, _, _, bVotes) = bVotes

type Naction = [State]

-- Create a Naction From a tuples List for each State at the beginning of Election. In the beginnig each candidate has 0 votes
nactionCreate:: [(String,Int)] -> Naction
nactionCreate ((n,r):xs) = [State | name <- n, representativeNumber<-r, 0, 0]

-- Return the State with the name equal to the String. Don't exists states with equals name
getState :: Naction -> String -> State
getState [] _ = null
getState ((n,_,_,_):xs) s =
    | n == s = State
    | otherwise = getState xs s


-- TODO 
addVotesToState :: State -> Int -> Int -> State

-- TODO
nactionAddVotes :: Naction -> [(String, Int, Int)] -> Naction

-- TODO
stateWinner :: State -> Candidate

-- TODO
electionWinner :: Naction -> Candidate

 

но мне трудно понять, как манипулировать данными / типами mas. Например, nactionCreate предполагается, что он будет работать как:

 > naction0 =createNaction [("North",4), ("Central",6), ("West",3)]
 

и тогда я мог бы сделать:

 > north0 = getState naction0 "North"
> representativesNumber north0
4
> aVotes north0
0
> bVotes north0
0
 

Я знаю, что функция, которую я уже создал, неверна (я имею в виду, я подозреваю), но я не могу понять, почему или как с ней работать… Может кто-нибудь мне помочь, пожалуйста?

PS: Я не хочу помогать с функциями, которые я еще не пытался создать.

Ответ №1:

На самом деле вы getState не создаете значение типа State ; вы просто используете конструктор типа в месте, где он не может быть использован. Вы получаете сообщение об ошибке, потому что конструктор данных не назван State . Вместо этого вы хотите вернуть значение, у которого было имя n .

Также нет такого значения, как null . Вы хотите, чтобы возвращаемый тип был Maybe State , используя Nothing для сигнализации сбоя и Just завершения успешного совпадения.

 getState :: Naction -> String -> Maybe State
getState [] _ = Nothing
getState (state@(n,_,_,_):xs) s =
    | n == s = Just state
    | otherwise = getState xs s 

Здесь имя state относится к началу списка State значений в целом, так что вам не нужно захватывать и повторять все значения в кортеже.