Skip to content

Instantly share code, notes, and snippets.

@Lucifier129
Created August 16, 2020 03:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lucifier129/798e9c8240290daedf6164e4f4c2dd4b to your computer and use it in GitHub Desktop.
Save Lucifier129/798e9c8240290daedf6164e4f4c2dd4b to your computer and use it in GitHub Desktop.
procedural abstraction
// data version
type DraftPost = {
kind: 'DraftPost';
content: string;
};
type ReviewingPost = {
kind: 'ReviewingPost';
content: string;
};
type RejectedPost = {
kind: 'RejectedPost';
content: string;
reason: string;
};
type ApprovedPost = {
kind: 'ApprovedPost';
content: string;
reason: string;
};
const createPost = (content: string = ''): DraftPost => {
return {
kind: 'DraftPost',
content,
};
};
const appendPostContent = (draftPost: DraftPost, content: string = '') => {
return {
...draftPost,
content: draftPost.content + content
}
}
const reviewPost = (draft: DraftPost): ReviewingPost => {
return {
kind: 'ReviewingPost',
content: draft.content,
};
};
const approvePost = (
reviewingPost: ReviewingPost,
reason: string = ''
): ApprovedPost => {
return {
kind: 'ApprovedPost',
content: reviewingPost.content,
reason,
};
};
const rejectPost = (
reviewingPost: ReviewingPost,
reason: string = ''
): RejectedPost => {
return {
kind: 'RejectedPost',
content: reviewingPost.content,
reason,
};
};
const rejectToDraftPost = (rejectedPost: RejectedPost): DraftPost => {
return {
kind: 'DraftPost',
content: rejectedPost.content,
};
};
const test = () => {
let draftPost = createPost('hello')
let newDraftPost = appendPostContent(draftPost, ' world')
let reviewingPost = reviewPost(newDraftPost)
let rejectedPost = rejectPost(reviewingPost, 'too bad')
let approvedPost = approvePost(reviewingPost, 'so good')
// uncomment to see the type error
// appendPostContent(reviewingPost, 'adsfasdf')
// reviewPost(approvedPost)
// approvePost(rejectedPost)
}
@Lucifier129
Copy link
Author

// codata version
type DraftPost = {
  content: string;
  review: () => ReviewingPost;
  append: (content: string) => DraftPost;
};

type ReviewingPost = {
  content: string;
  reject: (reason: string) => RejectedPost;
  approve: (reason: string) => ApprovedPost;
};

type RejectedPost = {
  content: string;
  reason: string;
  toDraft: () => DraftPost;
};

type ApprovedPost = {
  content: string;
  reason: string;
};

const createDraftPost = (content: string = ''): DraftPost => {
  return {
    content,
    review: () => createReviewingPost(content),
    append: (newContent = '') => createDraftPost(content + newContent),
  };
};

const createReviewingPost = (content: string = ''): ReviewingPost => {
  return {
    content,
    reject: (reason = '') => createRejectedPost(content, reason),
    approve: (reason = '') => createApprovedPost(content, reason),
  };
};

const createRejectedPost = (
  content: string = '',
  reason: string = ''
): RejectedPost => {
  return {
    content,
    reason,
    toDraft: () => createDraftPost(content),
  };
};

const createApprovedPost = (
  content: string = '',
  reason: string = ''
): ApprovedPost => {
  return {
    content,
    reason,
  };
};

const createPost = createDraftPost;

const test = () => {
  createPost('hello')
    .append(' ')
    .append('world')
    .review()
    .reject('too bad')
    .toDraft()
    .append(' some content')
    .review()
    .approve('so good');
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment