Skip to content

Instantly share code, notes, and snippets.

Take-home functional programming interview

This document is licensed CC0.

These are some questions to give a sense of what you know about FP. This is more of a gauge of what you know, it's not necessarily expected that a single person will breeze through all questions. For each question, give your answer if you know it, say how long it took you, and say whether it was 'trivial', 'easy', 'medium', 'hard', or 'I don't know'. Give your answers in Haskell for the questions that involve code.

Please be honest, as the interviewer may do some spot checking with similar questions. It's not going to look good if you report a question as being 'trivial' but a similar question completely stumps you.

Here's a bit more guidance on how to use these labels:

@aryairani
aryairani / monads.u
Last active March 29, 2020 20:39 — forked from pchiusano/monads.u
Converting between algebraic effects and monads
-- This gist shows how we can use abilities to provide nicer syntax for any monad.
-- We can view abilities as "just" providing nicer syntax for working with the
-- free monad.
ability Monadic f where
eval : f a -> a
-- Here's a monad, encoded as a first-class value with
-- two polymorphic functions, `pure` and `bind`
type Monad f = Monad (forall a . a -> f a) (forall a b . f a -> (a -> f b) -> f b)
package org.gtri.arfam.acs.interpreter;
import fj.F;
import fj.F2;
import fj.data.List;
public interface Operation<A> {
interface Free<A> {
scalaVersion := "2.11.7"
libraryDependencies += "org.scalaz" %% "scalaz-effect" % "7.2.2"
class Bind<A, B> implements Free<B> {
private final Operation<A> operation;
private final F<A, Free<B>> fInner;
private Bind(Operation<A> operation, F<A, Free<B>> fInner) {
this.operation = operation;
this.fInner = fInner;
}
if ((keys[KEY_JUMP] && jumptime < 0) || (jumptime < 0 && !grounded && !sliding && jumptime < 0)) {
dataPhysical.xa = jumpSpeedX;
dataPhysical.ya = -jumptime * jumpSpeedY;
jumptime++;
} else if (keys[KEY_JUMP] && mayJump && grounded) {
jumpSpeedX = 0;
jumpSpeedY = -1.9f;
jumptime = (int) JUMP_TIME;
dataPhysical.ya = jumptime * jumpSpeedY;
if ((jumptime < 0 && keys[KEY_JUMP]) || (jumptime < 0 && !grounded && !sliding)) {
dataPhysical.xa = jumpSpeedX;
dataPhysical.ya = -jumptime * jumpSpeedY;
jumptime++;
} else if ((grounded && mayJump && keys[KEY_JUMP]) || (mayJump && jumptime < 0 && !sliding)) {
jumpSpeedX = 0;
jumpSpeedY = -1.9f;
jumptime = (int) JUMP_TIME;
dataPhysical.ya = jumptime * jumpSpeedY;
grounded = false;
package edu.gatech.dt87.scalaverse
package object planner {
/**
* An ActionElement is either an Event or a Goal.
*
* @tparam S a state type
*/
sealed trait ActionElement[S]
case class Action[S](when: (S) => Boolean,
then: (S) => Either[String, S],
name: String = "")
{
def apply(state: S): Either[String, S] =
if (when(state)) then(state)
else Left(s"The system could not execute the action '$name'.")
}
case class Goal[S](actionSet: List[Action[S]], name: String = "") {