How to modify haskell function to remove duplicates [closed] - haskell

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have this haskell function that flattens a two deep list into one list. How can I edit it to make sure that it doesn't allow for duplicates? An example would be
flatten[['a'],[],['a','b']] --> ['a','b']
My current program would output
['a','a','b']
flatten :: [[a]] -> [a]
flatten [] = []
flatten ([]:vs) = flatten vs
flatten ((x:xs):vs) = x:flatten (xs:vs)

Skipping over duplicates in an unsorted list requires keeping a set of already-seen elements, and checking every incoming element.
Something like:
dedupliction_step :: [a] -> SetOf a -> [a] -> [a]
deduplication_step [] _ output = output
dedupliction_step (x:rest) already_seen output =
if x `belongsTo` already_seen then deduplication_step rest already_seen output
else deduplication_step rest updated_seen x:output where
updated_seen = putElementInto already_seen x
This gives you the idea. How do you implement SetOf and its related manipulations, depends on the problem at hand.
For short sets, you can use SetOf = List; then belongsTo = elem. It has a linear lookup time, though, so for long sets it becomes expensive.
For long sets, you can use e.g. a Data.Tree or Data.Set with logarithmic lookup and update time.
For short sets of numbers, Data.Bits could be considered; it's O(1) lookup and update, but limited to 32 or 64 values.

Related

Haskell search list of tuples [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I'm trying to make a program that searches through a list of tuples (Char, Bool) and returns true if there are any two conflicting elements within it. Two tuples are conflicting if they have the same value for the first element (Char) in the tuple but the second ones are different (Bool).
For example
[('a', True),('a', False)] returns False , 'a'='a' but True != False
[('a', True),('a', True) returns True. , 'a'='a' and True=True
[('a', True),('a', True), ('b', true), ('c', false)] returns true
ListofTupels :: [(a,a)] -> [a]
type ListofTupels = [(Char,Bool)]
The function is defined like this
searchValidity :: ListofTupels -> Bool
How to do this?
Use recursion. An empty list is vacuously valid:
type ListofTuples = [(Char,Bool)]
searchValidity :: ListOfTuples -> Bool
searchValidity [] = True
An non-empty list consists of a valid tail and a head that doesn't invalidate the list.
searchValidity ((c, b):rest) = searchValidity rest && ...
I leave filling in ... as an exercise. The lookup function in the Prelude should be useful.
(I leave it as a further exercise to do this in subquadratic time. Using lookup at each step slows this down greatly.)

Composing Haskell tree structures

I got a problem with thinking recursively in Haskell.
I am trying to build a survey application where questions conditionally lead to new questions based on the user's answers.
I got:
- Questions - a list of questions
- QuestionPaths - a list of question paths of questions which lead to new questions
- Answers a list of user's answers
You can think of QuestionPaths as a list of tuples where:
type QuestionPath = (QuestionId, AnswerChoice, NextQuestionId)
Basically this would read: If user answers a question QuestionId with an answer AnswerChoice, ask him NextQuestionId next.
I have attempted to model this problem domain with multiway trees (nodes can have multiple children):
data YesNo = Yes | No
data AnswerChoice = Skip
| Boolean YesNo
| ChooseOne [Text]
type Condition = AnswerChoice
data QuestionTree = QuestionNode {
question :: Question
, condition :: Condition
, userAnswer :: Maybe AnswerChoice
, children :: QuestionForest
}
type QuestionForest = [QuestionTree]
Unfortunately, I am clueless now on how to write algorithms that compose trees like this.
I basically need these kinds of functions for composition and traversal:
-- Constructs the tree from seed data
constructTree :: Questions -> QuestionPaths -> Answers -> QuestionTree
-- | Inserts answer to question in the tree
answerQuestion :: Question -> AnswerChoice
-- | Fetches the next unanswered question by traversing the tree.
getNextUnanswered :: QuestionTree -> Question
Can you please help me understand what would be the best way to construct and traverse a tree such as this?
What I'd do in such a case, is to store the answers in a separate data structure - not to insert them in the questions tree; put the answers in a separate list/Set, or in a file or database, and let the questions tree be immutable.
In order to keep track of which questions remain to be asked, you can "consume" the tree - keep your program state pointing to the next question, throwing away the questions already answered (letting the garbage collector reclaim them).
I'd design the tree like this:
data AllowedAnswers = YesOrNo {
ifUserAnsweredYes :: QuestionTree,
ifUserAnsweredNo :: QuestionTree
}
| Choices [(Text, QuestionTree)]
data QuestionTree = Question {
description :: Text
, allowedAnswers :: AllowedAnswers
, ifUserSkipsThisQuestion :: QuestionTree
}
| EndOfQuestions
Notice several things:
You don't have to worry about multiple possible paths leading to the same question - you can place the same QuestionTree node in multiple places, and it will be shared (Haskell won't create multiple copies of it)
This design has no place to hold the user's answers - they are stored elsewhere (i.e. a list somewhere, or a file) - no need to mutate the question tree.
As the user answers questions, just move your "pointer" to the next QuestionTree, depending on what the user answered.
As for "how to construct this tree from the (QuestionId, AnswerChoice, NextQuestionId) list" - I think I'd first convert it into a map: ```Map QuestionId [(AnswerChoice, Maybe QuestionId)], then I'd construct the tree by, starting with the ID of the first question, and fetching its immediate children from the Map, build the subtrees.
Example (for a very simplified case where the only possible answers are "yes" or "no", with no skipping allowed):
buildTree questionMap questionId = case Map.lookup questionId questionMap of
Nothing -> EndOfQuestions
Just (description, [("yes", nextQuestionIdIfYes), ("no", nextQuestionIdIfNo)]) ->
Question { description = description
, allowedAnswers = YesOrNo {
ifUserAnsweredYes = buildTree questionMap nextQuestionIdIfYes
, ifUserAnsweredNo = buildTree questionMap nextQuestionIdIfNo
}
, ifUserSkipsThisQuestion = EndOfQuestions
}
If you are wondering "why not just use the Map directly?" - yes, you could (and often it will be the right solution), but consider:
The QuestionTree structure expresses the programmer's intention more idiomatically than a Map of Id -> Thing
It is structurally guaranteed to have a child QuestionTree whenever pertinent - no need to do Map.lookup, which will return a Maybe, which you must verify that contains a Just (even when you know there is going to be a next question, even if it is EndOfQuestions)

How to find time complexity of this program? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have a data list.
db = [("Ada","works", "IBM")
,("Alice","director", "Ada")
,("Tom","works", "IBM")
,("Tommy","director", "Tom")
,("IBM","isat", "CA")
,("CA","in", "USA")
]
ask db = map (\(x,y,z) -> (z == "IBM")) db
How to calculate the complexity of O(n)?
If I want to get the result by the length of list 2,5,10.O(n) is same like 2,5,10?And If I do
trans2 db = concat (map ((x,y,z) -> concat (map((x',y',z') -> if (z==x') then [] else [(x,y ++ "." ++ y',z')] else []) db)) db )
How can I calculate the O(n)? The runtime of program? The timming complexity
The question is unclear and I expect it will soon be closed. Briefly.
O(n) is a complexity. If you know O(n) and you wanted complexity then you're done.
The length of the list (2, 5, 10, what have you) is not a factor in the complexity in this case since the length is what the n is representing.
There is no code that will calculate the complexity of the algorithm automatically. It is a manual analysis.

Chop the Hydra in Haskell [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I was working on a version of the problem that's here : http://blog.gja.in/2014/01/functional-programming-101-with-haskell.html#.WIi0J7YrKHo
However if I were to give in an input of chop chop [1,0,0,0], it should return [0,3,0,0]. I tried playing around with the code that was given on the above website however I can't seem to be figuring it out. I've also only started learning Haskell 3-4 days ago so I'm not sure what the right direction is to go on.
Thank you in advance!
I think you misunderstood the intended behavior. As rampion points out,
chop [1,0,0,0] should result in [0,0,0]. I don't understand, where you get [0,3,0,0], but I'll walk you through a little.
First, the definition of chop, with some comments that allow me to refer to each part of the definition.
chop [] = [] --chopNull
chop (1:xs) = xs --chopHead1
chop (n:xs) = (replicate (n - 1) (n - 1)) ++ xs --chopHeadN
You asked about chop chop [1,0,0,0]. This isn't valid code. I'll assume you meant chop (chop [1,0,0,0]). Taking this as the starting point, I'll perform a bit of equational reasoning. That is, I'll transform the program fragment in question by substituting the relevant part of the definition. Each line has a comment indicating how the current line was calculated from the previous one.
chop (chop [1,0,0,0])
= chop (chop (1:0:0:0:[]) --De-sugaring of List
= chop (chop (1:xs)) --Let xs = 0:0:0:[] = [0,0,0]
= chop (xs) --chopHead1
= chop (0:0:0:[]) --def of xs
= (replicate (0 - 1) (0 - 1)) ++ (0:0:[]) --chopHeadN
= [] ++ (0:0:[]) --From definition of replicate
= (0:0:[]) --From defintion of (++)
= [0,0] --re-sugaring
I do a few loose things above. Notably I equate xs to (0:0:0:[]) in the comment. This is just to make it clear how that particular substitution is satisfied by the pattern match in the definition. Next, I used the chopHeadN definition to match the case where n=0, as it is the first thing that matches. You'll have to trust me on the definition of replicate and (++).
So that is what that particular call should be doing. Generally however, if you don't know what a particular function does, it is a good idea to start with some simpler input. For lists, an empty list [] or singleton's, [n] are good starting points. Then move on to two element lists. Like in this example, you can cut out part of a definition and inspect what that part does on known data. Do it yourself in ghci. (Actually, that's what I did for the replicate (0-1) (0-1) expression. I thought it would be an error.)

How to call a function returning a tuple in another function in haskell? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I have two functions like these:
notice_objects_at::String -> IO()
notice_objects_at place = do
let (X,Y) = at place
putStrLn ("There is a" ++ show X ++ "," ++ show Y ++ "here.")
putStrLn "Hi"
at::String-> (String, String)
at place =
case place of
"bedroom" -> ("fly", "light switch")
"den" -> ("flyswatter", "light switch")
from the 'at' function I am returning a tuple, which I want to store to two variables X and Y in the notice_objects_at function. But, I'm getting an error that:
Not in scope: data constructor ‘X’
Not in scope: data constructor ‘Y’
Not in scope: data constructor ‘X’
Not in scope: data constructor ‘Y’
What is wrong?
Haskell syntax relies on the capitalisation of names. As described here:
Anything that starts with a capital letter is either a concrete type
or a data constructor. Lower-case-starting names are reserved for
function names and variables, including type variables.
So when you bind names to the elements of the tuple in:
let (X,Y) = at place
you need lowercase names:
let (x,y) = at place
(and adjust the names wherever else they are used, of course!)
Otherwise Haskell interprets these names as data constructors, but of course cannot find their definition anywhere, hence your error messages.
See also Why does Haskell force data constructor's first letter to be upper case?

Resources