Skip to content

Instantly share code, notes, and snippets.

@watiko
Last active March 22, 2019 07:30
Show Gist options
  • Save watiko/88f9c1f5a64cc6805e07774d5e91305a to your computer and use it in GitHub Desktop.
Save watiko/88f9c1f5a64cc6805e07774d5e91305a to your computer and use it in GitHub Desktop.
#include <iostream>
#include <cstdlib>
template<typename T>
struct OrdTraits;
// int 向けにテンプレートの特殊化
template<> struct OrdTraits<int> {
static bool less(const int &x, const int &y) {
return x < y;
}
};
// concept を定義
template<typename T>
concept bool Ord = requires (T x) {
{ OrdTraits<T>::less(x, x) } -> bool
};
template <class T> requires Ord<T> // requires で T が Ord<T> を満たすことを要求
T max(const T &x, const T &y)
{
return OrdTraits<T>::less(x, y) ? y : x;
}
int main()
{
std::cout << max(1, 10) << std::endl;
}
trait Ord[A] {
def less(x: A, y: A): Boolean
}
object OrdInstances {
// Ord[A] に一つしか抽象メソッドがないため SAM Conversion が行われる
// http://eed3si9n.com/ja/scala-2.12.0
implicit val intOrd: Ord[Int] = (x: Int, y: Int) => x < y
}
object Wandbox {
// implicit な値をこのスコープに導入
import OrdInstances._
// カリー化されている最後の引数リストで Ord[A] の暗黙の値を受け取っている
def max[A](x: A, y: A)(implicit ord: Ord[A]): A
= if (ord.less(x, y)) y else x
def main(args: Array[String]): Unit = {
// max(1, 10)(intOrd) でも同じ
println(max(1, 10))
}
}
import Prelude hiding (Ord, max) -- GHC の標準に Ord, max が存在するので明示的に使わない設定する
class Ord a where
less :: a -> a -> Bool
instance Ord Int where
less x y = x < y
max :: Ord a => a -> a -> a
max x y = if (less x y) then y else x
main :: IO ()
main = putStrLn $ show $ max (1 :: Int) 10 -- リテラルの型を明示しないとこの場合は候補が絞れず怒られる
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment