import Data.Map as DataMap newtype Marker marker = Marker marker deriving (Eq, Show) data Node identifier marker = Node identifier (Marker marker) instance (Eq identifier, Eq marker) => Eq (Node identifier marker) where (==) (Node i1 m1) (Node i2 m2) = i1 == i2 && m1 == m2 instance (Ord identifier, Eq marker) => Ord (Node identifier marker) where compare (Node i1 _) (Node i2 _) = compare i1 i2 instance (Show identifier, Show marker) => Show (Node identifier marker) where show (Node node (Marker marker)) = "Node " ++ show node ++ ": " ++ show marker data Graph identifier marker = Graph (Map identifier (Node identifier marker)) (Map identifier [identifier]) instance Ord identifier => Semigroup (Graph identifier marker) where (<>) (Graph nodesA adjazenzListA) (Graph nodesB adjazenzListB) = Graph (DataMap.union nodesA nodesB) (DataMap.unionWith (++) adjazenzListA adjazenzListB) instance Ord identifier => Monoid (Graph identifier marker) where mempty = Graph empty empty instance (Ord identifier, Eq marker) => Eq (Graph identifier marker) where (==) (Graph nodesA adjazenzListA) (Graph nodesB adjazenzListB) = nodesA == nodesB && adjazenzListA == adjazenzListB instance (Ord identifier, Show identifier, Show marker) => Show (Graph identifier marker) where show (Graph nodes adjazenzList) = "Graph:" ++ Prelude.foldr (\node result -> "\n" ++ show (nodes!node) ++ " " ++ show (adjazenzList!node) ++ result ) "" (DataMap.keys nodes) -- Returns a list of all graph start nodes that have no incoming edges allStartNodes :: Ord identifier => Graph identifier marker -> [Node identifier marker] allStartNodes (Graph nodes adjazenzList) = Prelude.foldr (\node resultList -> -- für alle Knoten if notElem node targets -- überprüft, dass der Knoten in keiner Adjazenz-Unterliste vorkommt. Heißt keine eingehenden Kanten then [nodes ! node] ++ resultList -- hat der Knoten keine eingehenden Kanten wir dieser der Liste hinzugefügt else resultList -- hat der Knoten eingehenden Kanten wird die Liste nicht verändert ) [] $ DataMap.keys adjazenzList where targets = concat $ DataMap.elems adjazenzList -- alle Zielknoten aller Kanten als eine Liste -- Checks if the given path exists in the grpah checkPath :: (Ord identifier, Eq identifier, Eq marker) => Graph identifier marker -> [identifier] -> Bool checkPath _ [] = True checkPath (Graph _ adjazenzList) (node:[]) = DataMap.member node adjazenzList -- check that start node is in graph checkPath (Graph nodes adjazenzList) (identifier:nextIdentifier:[]) = checkPath (Graph nodes adjazenzList) [identifier] -- check that start node is in graph && checkPath (Graph nodes adjazenzList) [nextIdentifier] -- check that next node is in graph && test identifier nextIdentifier adjazenzList -- check that next node is successor of node checkPath (Graph nodes adjazenzList) (identifier:nextIdentifier:identifiers) = checkPath (Graph nodes adjazenzList) ([identifier] ++ [nextIdentifier]) -- check that both nodes are in the graph and the second node is successor of the first node && checkPath (Graph nodes adjazenzList) ([nextIdentifier] ++ identifiers) -- check for all following nodes without the first node test identifier nextIdentifier adjazenzList = do followers <- DataMap.lookup identifier adjazenzList putStrLn followers result <- elem nextIdentifier followers return True main = putStrLn "Hello, World!"
Write, Run & Share Haskell code online using OneCompiler's Haskell online compiler for free. It's one of the robust, feature-rich online compilers for Haskell language, running the latest Haskell version 8.6. Getting started with the OneCompiler's Haskell editor is easy and fast. The editor shows sample boilerplate code when you choose language as Haskell and start coding.
OneCompiler's Haskell online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample Haskell program which takes name as input and prints hello message with your name.
main = do
name <- getLine
putStrLn ("Hello " ++ name ++ ", Happy learning!")
Haskell is purely a functional programming language which was introduced in 1990's.
Data-type | Description |
---|---|
Numbers | Haskell is intelligent to identify numbers without specifying data type |
Characters | Haskell is intelligent to identify characters and strings without specifying data type |
Tuple | To declare multiple values in a single data type. Tuples are represented in single paranthesis. For example (10, 20, 'apple') |
Boolean | To represent boolean values, true or false |
List | To declare same type of values in a single data type. Lists are represented in square braces.For example [1, 2, 3] or `['a','b','c','d'] |
When ever you want to perform a set of operations based on a condition or set of conditions, then If-Else/ Nested-If-Else are used.
main = do
let age = 21
if age > 18
then putStrLn "Adult"
else putStrLn "child"
Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity. Functions play an important role in Haskell, since it is a purely functional language.
multiply :: Integer -> Integer -> Integer --declaration of a function
multiply x1 x2 = x1 * x2 --definition of a function
main = do
putStrLn "Multiplication value is:"
print(multiply 10 5) --calling a function