Skip to content

Instantly share code, notes, and snippets.

@taku0
Created September 9, 2016 15:15
Show Gist options
  • Save taku0/f5fc2a12e3f62c67109fa01e1966615c to your computer and use it in GitHub Desktop.
Save taku0/f5fc2a12e3f62c67109fa01e1966615c to your computer and use it in GitHub Desktop.
# coding: utf-8
# たとえば次のような関数を考える。
def foo(array_or_hash)
if array_or_hash.respond_to?(:values)
# Hashっぽい
array_or_hash.values.join(", ")
else
# きっとArray
array_or_hash.join(", ")
end
end
# この関数は以下のように、Hashでも配列でも呼べる、というのを意図している。
foo({:a => 1, :b => 2}) //=> "1, 2"
foo([1, 2]) //=> "1, 2"
# さて、これに対して単純な型推論をしてみると、次のようになる。
# foo: ∀a. { values: { join: String -> a }, join: String -> a } → a
# 日本語で書くと、
# - fooは任意の型aについて、T(後述)を受けとりaを返す。
# - Tはvaluesプロパティとjoinメソッドを持つオブジェクトの型である。
# - valuesプロパティはjoinメソッドを持つオブジェクトを返す。
# - 2つのjoinメソッドはどちらもStringを受けとり、aを返す。
# となる。
#
# しかし、Hashも配列もこの型には適合しない。困った。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment