Skip to content

Instantly share code, notes, and snippets.

@Pzixel
Last active September 29, 2019 17:41
Show Gist options
  • Save Pzixel/e1e159143c279e7c5df4633640ef7989 to your computer and use it in GitHub Desktop.
Save Pzixel/e1e159143c279e7c5df4633640ef7989 to your computer and use it in GitHub Desktop.
Haskell vs GO: Tree mapping
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
class Program
{
class Comment
{
public int Id { get; set; }
public string Title { get; set; }
public override string ToString() => $"{Id} - {Title}";
}
private static Task<Comment> GetCommentById(int id) =>
new HttpClient().GetStringAsync($"https://jsonplaceholder.typicode.com/todos/{id}")
.ContinueWith(n => JsonConvert.DeserializeObject<Comment>(n.Result));
private static async Task<Tree<Comment>> GetCommentsTree(Tree<int> tree)
{
var children = Task.WhenAll(tree.Children.Select(GetCommentsTree));
var value = await GetCommentById(tree.Value);
var childrenResults = await children;
return new Tree<Comment> { Value = value, Children = childrenResults };
}
private static async Task Main()
{
var tree = Tr(1, new[] { Tr(2), Tr(3, new[] { Tr(4), Tr(5) }) });
PrintTree(tree);
var comment_tree = await GetCommentsTree(tree);
PrintTree(comment_tree);
}
class Tree<T>
{
public T Value { get; set; }
public Tree<T>[] Children { get; set; }
}
private static void PrintTree<T>(Tree<T> tree, string intendantion = "")
{
Console.WriteLine(intendantion + tree.Value);
foreach (var child in tree.Children)
{
PrintTree(child, intendantion + " ");
}
}
static Tree<T> Tr<T>(T value, Tree<T>[] children = null) => new Tree<T> { Value = value, Children = children ?? Array.Empty<Tree<T>>() };
}
1
2
3
4
5
1 - delectus aut autem
2 - quis ut nam facilis et officia qui
3 - fugiat veniam minus
4 - et porro tempora
5 - laboriosam mollitia et enim quasi adipisci quia provident illum
package main
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"sync"
"time"
)
func getCommentById(i int) comment {
result := &comment {}
err := getJson("https://jsonplaceholder.typicode.com/todos/"+strconv.Itoa(i), result)
if err != nil {
panic(err)
}
return *result
}
func getJson(url string, target interface{}) error {
var myClient = &http.Client{Timeout: 10 * time.Second}
r, err := myClient.Get(url)
if err != nil {
return err
}
defer r.Body.Close()
return json.NewDecoder(r.Body).Decode(target)
}
func getCommentsTree(root intTree) commentTree {
result := commentTree{}
var wg sync.WaitGroup
getCommentsTreeInternal(&result, root, &wg)
wg.Wait()
return result
}
func getCommentsTreeInternal(resNode *commentTree, node intTree, wg *sync.WaitGroup) {
wg.Add(len(node.children))
for _, res := range node.children {
child := &commentTree{}
resNode.children = append(resNode.children, child)
res := res
go func() {
defer wg.Done()
getCommentsTreeInternal(child, res, wg)
}()
}
resNode.value = getCommentById(node.id)
}
func main() {
tree := intTree{
id: 1,
children: []intTree{
{
id: 2,
children: []intTree{},
},
{
id: 3,
children: []intTree{
{
id: 4,
},
{
id: 5,
},
},
},
},
}
showIntTree(tree)
commentsTree := getCommentsTree(tree)
showCommentsTree(commentsTree)
}
type intTree struct {
id int
children []intTree
}
type comment struct {
Id int
Title string
}
type commentTree struct {
value comment
children []*commentTree
}
func showIntTree(tree intTree) {
showIntTreeInternal(tree, "")
}
func showIntTreeInternal(tree intTree, indent string) {
fmt.Printf("%v%v\n", indent, tree.id)
for _, child := range tree.children {
showIntTreeInternal(child, indent+" ")
}
}
func showCommentsTree(tree commentTree) {
showCommentsTreeInternal(tree, "")
}
func showCommentsTreeInternal(tree commentTree, indent string) {
fmt.Printf("%v%v - %v\n", indent, tree.value.Id, tree.value.Title)
for _, child := range tree.children {
showCommentsTreeInternal(*child, indent+" ")
}
}
1
2
3
4
5
1 - delectus aut autem
2 - quis ut nam facilis et officia qui
3 - fugiat veniam minus
4 - et porro tempora
5 - laboriosam mollitia et enim quasi adipisci quia provident illum
{-# LANGUAGE DeriveGeneric #-}
import Data.Tree
import Data.Maybe
import Network.Wreq
import GHC.Generics
import Data.Aeson
import Control.Lens
import Control.Concurrent.Async
data Comment = Comment {
title :: String
, id :: Int
} deriving (Generic, Show)
instance FromJSON Comment
getCommentById :: Int -> IO Comment
getCommentById i = do
response <- get $ "https://jsonplaceholder.typicode.com/todos/" ++ show i
let comment = decode (response ^. responseBody) :: Maybe Comment
return $ fromJust comment
main :: IO ()
main = do
let tree = Node 1 [Node 2 [], Node 3 [Node 4 [], Node 5 []]]
Prelude.putStrLn . drawTree . fmap show $ tree
comments_tree <- mapConcurrently getCommentById tree
Prelude.putStrLn . drawTree . fmap show $ comments_tree
1
|
+- 2
|
`- 3
|
+- 4
|
`- 5
"Comment {title = \"delectus aut autem\", id = 1}"
|
+- "Comment {title = \"quis ut nam facilis et officia qui\", id = 2}"
|
`- "Comment {title = \"fugiat veniam minus\", id = 3}"
|
+- "Comment {title = \"et porro tempora\", id = 4}"
|
`- "Comment {title = \"laboriosam mollitia et enim quasi adipisci quia provident illum\", id = 5}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment