File: value/core/morph/enumerator.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Umu#6
  module: Value#8
  module: Core#10
has properties
function: make_enumerator / 2 #181
function: make_user_enumerator / 2 #189
  module: Morph#12
  module: Enum#14
  class: Abstract#16
inherits from
  Abstract ( Umu::Value::Core::Morph )
has properties
class method: make / 1 #17
class method: meth_make_empty / 3 #29
attribute: source [R] #34
method: initialize / 1 #36
method: to_s #43
method: meth_cons / 4 #53
  class: Provider#67
inherits from
  Abstract ( Umu::Value::Core::Morph::Enum )
has properties
constant: TYPE_SYM #68
attribute: dest [R] #71
method: initialize / 2 #73
method: meth_dest / 3 #83
  class: User#135
inherits from
  Abstract ( Umu::Value::Core::Morph::Enum )
has properties
constant: TYPE_SYM #136
class method: meth_make / 5 #144
attribute: fn_dest [R] #152
method: initialize / 2 #154
method: meth_dest / 3 #164

Class Hierarchy

Code

   1  # coding: utf-8
   2  # frozen_string_literal: true
   3 
   4 
   5 
   6  module Umu
   7 
   8  module Value
   9 
  10  module Core
  11 
  12  module Morph
  13 
  14  module Enum
  15 
  16  class Abstract < Morph::Abstract
  17      def self.make(xs)
  18          ASSERT.kind_of xs, ::Array
  19 
  20          VC.make_list xs
  21      end
  22 
  23 
  24      define_class_method(
  25          :meth_make_empty,
  26          :empty, [],
  27          [], VCM::List::Abstract
  28      )
  29      def self.meth_make_empty(loc, env, _event)
  30          VC.make_nil
  31      end
  32 
  33 
  34      attr_reader :source
  35 
  36      def initialize(source)
  37          ASSERT.kind_of source,  VC::Top
  38 
  39          @source = source
  40      end
  41 
  42 
  43      def to_s
  44          format "#Enum<%s>", self.source.to_s
  45      end
  46 
  47 
  48      define_instance_method(
  49          :meth_cons,
  50          :cons, [],
  51          [VC::Top], VCM::List::Abstract
  52      )
  53      def meth_cons(loc, env, _event, value)
  54          ASSERT.kind_of value, VC::Top
  55 
  56          raise X::NotImplemented.new(
  57                      loc,
  58                      env,
  59                      "cons: Emnumerator morph is not be constructible"
  60                  )
  61      end
  62  end
  63  Abstract.freeze
  64 
  65 
  66 
  67  class Provider < Abstract
  68      TYPE_SYM = :ProviderEnum
  69 
  70 
  71      attr_reader :dest
  72 
  73      def initialize(source, dest)
  74          ASSERT.kind_of source,  VC::Top
  75          ASSERT.kind_of dest,    ::Proc
  76 
  77          super(source)
  78 
  79          @dest = dest
  80      end
  81 
  82 
  83      def meth_dest(_loc, _env, _event)
  84          val_opt = self.dest.call self.source
  85          ASSERT.kind_of  val_opt,            VCU::Option::Abstract
  86          ASSERT.kind_of  val_opt.contents,   VC::Top
  87 
  88          val_opt
  89      end
  90  end
  91  Provider.freeze
  92 
  93 
  94  =begin
  95  HOW TO USE UserEnum
  96 
  97      * Same to: [1 ..5].to-list
  98 
  99          > fun rec fn-dest = x -> (
 100          *     if x <= 5 then Some (x, &UserEnum.make (x + 1) fn-dest)
 101          *               else NONE
 102          * )
 103          > &UserEnum.make 1 fn-dest.to-list
 104          val it : Cons = [1, 2, 3, 4, 5]
 105 
 106      * Same to: [1 ..5].map to-s
 107 
 108          > &UserEnum.make 1 fn-dest.map to-s
 109          val it : Cons = ["1", "2", "3", "4", "5"]
 110 
 111      * Same to: [1 ..5].select odd?
 112 
 113          > &UserEnum.make 1 fn-dest.select odd?
 114          val it : Cons = [1, 3, 5]
 115 
 116      * Same to: [|to-s x| val x <- [1 ..5] if odd? x]
 117 
 118          > [|to-s x| val x <- &UserEnum.make 1 fn-dest if odd? x]
 119          val it : Cons = ["1", "3", "5"]
 120 
 121      * Same to: STDIN.each-line.for-each { s -> print <| "- " ^ s }
 122 
 123          > fun rec fn-dest' = io -> case io.gets of {
 124          *   | &None   -> NONE
 125          *   | &Some s -> Some (s, &UserEnum.make io fn-dest')
 126          * }
 127          > &UserEnum.make STDIN fn-dest'.for-each { s -> print <| "- " ^ s }
 128          aaa [Enter]
 129          - aaa
 130          bbb [Enter]
 131          - bbb
 132          [Ctrl]+[d]
 133          >
 134  =end
 135  class User < Abstract
 136      TYPE_SYM = :UserEnum
 137 
 138 
 139      define_class_method(
 140          :meth_make,
 141          :make, [],
 142          [VC::Top, VC::Fun], self
 143      )
 144      def self.meth_make(loc, env, event, source, fn_dest)
 145          ASSERT.kind_of source,  VC::Top
 146          ASSERT.kind_of fn_dest, VC::Fun
 147 
 148          VC.make_user_enumerator source, fn_dest
 149      end
 150 
 151 
 152      attr_reader :fn_dest
 153 
 154      def initialize(source, fn_dest)
 155          ASSERT.kind_of source,  VC::Top
 156          ASSERT.kind_of fn_dest, VC::Fun
 157 
 158          super(source)
 159 
 160          @fn_dest = fn_dest
 161      end
 162 
 163 
 164      def meth_dest(loc, env, event)
 165          val_opt = self.fn_dest.apply self.source, [], loc, env.enter(event)
 166          VC.validate_option val_opt, 'dest', loc, env
 167 
 168          ASSERT.kind_of val_opt, VCU::Option::Abstract
 169      end
 170  end
 171  Provider.freeze
 172 
 173  end # Umu::Value::Core::Morph::Enum
 174 
 175  end # Umu::Value::Core::Morph
 176 
 177 
 178 
 179  module_function
 180 
 181      def make_enumerator(source, dest)
 182          ASSERT.kind_of source,  VC::Top
 183          ASSERT.kind_of dest,    ::Proc
 184 
 185          Morph::Enum::Provider.new(source, dest).freeze
 186      end
 187 
 188 
 189      def make_user_enumerator(source, fn_dest)
 190          ASSERT.kind_of source,  VC::Top
 191          ASSERT.kind_of fn_dest, VC::Fun
 192 
 193          Morph::Enum::User.new(source, fn_dest).freeze
 194      end
 195 
 196  end # Umu::Value::Core
 197 
 198  end # Umu::Value
 199 
 200  end # Umu