In this article, I'll explain why implementing numbers with just algebraic datatypes is desirable. I'll then talk about common implementations of FFT (Fast Fourier Transform) and why they hide inherent inefficiencies. I'll then show how to implement integers and complex numbers with just algebraic datatypes, in a way that is extremely simple and elegant. I'll conclude by deriving a pure functional implementation of complex FFT with just datatypes, no floats.
Think of all the arguments you've heard as to why static typing is desirable — every single one of those arguments applies equally well to using types to represent error conditions.
An odd thing I’ve observed about the Scala community is how many of its members believe that a) a language with a sophisticated static type system is very valuable; and b) that using types for error handling is basically a waste of time. If static types are useful—and if you like Scala, presumably you think they are—then using them to represent error conditions is also useful.
Here's a little secret of functional programming: errors aren't some special thing that operate under a different set of rules to everything else. Yes, there are a set of common patterns we group under the loose heading "error handling", but fundamentally we're just dealing with more values. Values that can have types associated with them. There's absolutely no reason why the benefits of static ty
#![feature(generic_associated_types)] | |
#[allow(dead_code)] | |
trait Functor { | |
type Unwrapped; | |
type Wrapped<B>: Functor; | |
fn map<F, B>(self, f: F) -> Self::Wrapped<B> | |
where | |
F: FnMut(Self::Unwrapped) -> B; |
def hash(a: A): Int
makes me sad. What about hashing to 64 bits or SL2 Fp?def MapHash[A, B: Hash]: Hash[Map[A, B]]
is a bit odd. Why notA: Hash
?reflexiveLaw + symmetryLaw + transitivityLaw
is too weak for "equality". This defines a general equivalence relationship only.val AnyEqual: Equal[Any]
is worrisome, considering all the resolution bugs!val DoubleEqual: Equal[Double]
should be implemented usingjava.lang.Double.doubleToRawLongBits
.- A combintation of [
trait Ord[-A] extends Equal[A]
](https://github.com/zio/zi
{ pkgs ? import <nixpkgs> {} }: { | |
test = pkgs.nixosTest ./test.nix; | |
} |
I've been fiddling about with an idea lately, looking at how higher-kinded types can be represented in such a way that we can reason with them in Rust here and now, without having to wait a couple years for what would be a significant change to the language and compiler.
There have been multiple discussions on introducing higher-ranked polymorphism into Rust, using Haskell-style Higher-Kinded Types (HKTs) or Scala-looking Generalised Associated Types (GATs). The benefit of higher-ranked polymorphism is to allow higher-level, richer abstractions and pattern expression than just the rank-1 polymorphism we have today.
As an example, currently we can express this type:
import akka.actor.ActorSystem | |
import akka.kafka.ConsumerMessage.CommittableMessage | |
import akka.kafka.scaladsl.Consumer | |
import akka.kafka.{ ConsumerSettings, Subscriptions } | |
import akka.stream.ActorMaterializer | |
import akka.stream.scaladsl.{ Keep, Sink => AkkaSink } | |
import org.apache.kafka.common.serialization.StringDeserializer | |
import scalaz.zio._ | |
import scalaz.zio.stream.Sink | |
import scalaz.zio.interop.reactiveStreams._ |
package fpmax | |
import scala.util.Try | |
import scala.io.StdIn.readLine | |
object App0 { | |
def main: Unit = { | |
println("What is your name?") | |
val name = readLine() |
import re | |
import os | |
import glob | |
import pandas as pd | |
import matplotlib.pyplot as plt | |
from collections import OrderedDict | |
fig_size = [12, 9] |