diff options
| author | muqiuhan <[email protected]> | 2023-06-28 13:53:29 +0000 |
|---|---|---|
| committer | muqiuhan <[email protected]> | 2023-06-28 13:53:29 +0000 |
| commit | 2dea5fe63a51145a33920cae54530b1ee0ffb6bb (patch) | |
| tree | 1f14ff40238809e29be50b02bd7b0ab7e183661a /2023/06/28/OOP-Visitors在Polymorphic情况下的类型错误 | |
| parent | 6f776f55fea31dd12e5af18af519ac7d02dd7f4e (diff) | |
| download | blog-2dea5fe63a51145a33920cae54530b1ee0ffb6bb.tar.gz | |
deploy: e49b6fef933475ec68ea65dc1d0141a2bad3e1a4
Diffstat (limited to '2023/06/28/OOP-Visitors在Polymorphic情况下的类型错误')
| -rw-r--r-- | 2023/06/28/OOP-Visitors在Polymorphic情况下的类型错误/index.html | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/2023/06/28/OOP-Visitors在Polymorphic情况下的类型错误/index.html b/2023/06/28/OOP-Visitors在Polymorphic情况下的类型错误/index.html new file mode 100644 index 00000000..2f715eea --- /dev/null +++ b/2023/06/28/OOP-Visitors在Polymorphic情况下的类型错误/index.html @@ -0,0 +1,243 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8"> +<meta name="viewport" + content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> +<meta http-equiv="X-UA-Compatible" content="ie=edge"> + + <meta name="author" content="含暮秋"> + + + <meta name="subtitle" content="暮秋小屋"> + + + <meta name="description" content="不卑不亢的码农, 朴素的民谣诗人"> + + + <meta name="keywords" content="韩暮秋,MuqiuHan"> + + + + +<title>OOP Visitors在Polymorphic情况下的类型错误 | 暮秋小屋</title> + + + + + +<style> + @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&family=Roboto+Mono&display=swap'); +</style> + + + + <!-- stylesheets list from _config.yml --> + + <link rel="stylesheet" href="/css/style.css"> + + + + + + <!-- scripts list from _config.yml --> + + <script src="/js/frame.js"></script> + + + + + + <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script> + <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> + + + + + + + + <!-- hexo injector head_end start --> +<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css"> + +<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/style.css"> +<!-- hexo injector head_end end --><meta name="generator" content="Hexo 6.3.0"></head> + <body> + <div class="mask-border"> + </div> + + <div class="wrapper"> + + <div class="header"> + <div class="flex-container"> + <div class="header-inner"> + <div class="site-brand-container"> + <a href="/"> + + 暮秋小屋 + + </a> + </div> + <div id="menu-btn" class="menu-btn" onclick="toggleMenu()"> + Menu + </div> + <nav class="site-nav"> + <ul class="menu-list"> + + + <li class="menu-item"> + <a href="/">主页</a> + </li> + + + + <li class="menu-item"> + <a href="/tags/Technique/">技术</a> + </li> + + + + <li class="menu-item"> + <a href="/Projects">项目</a> + </li> + + + + <li class="menu-item"> + <a href="/categories/gallery/">日记本</a> + </li> + + + + <li class="menu-item"> + <a href="/about">关于</a> + </li> + + + + </ul> + </nav> + </div> + </div> +</div> + + + <div class="main"> + <div class="flex-container"> + <article id="post"> + + + <div class="post-head"> + <div class="post-info"> + <div class="tag-list"> + + + <span class="post-tag"> + <a href="/tags/Technique/"> + Technique + </a> + </span> + + <span class="post-tag"> + <a href="/tags/OCaml/"> + OCaml + </a> + </span> + + + </div> + <div class="post-title"> + + + OOP Visitors在Polymorphic情况下的类型错误 + + + </div> + <span class="post-date"> + Jun 28, 2023 + </span> + </div> + <div class="post-img"> + + <div class="h-line-primary"></div> + + </div> +</div> + <div class="post-content"> + <p>像Java里面:</p> +<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">interface</span> <span class="title class_">Tree</span> {</span><br><span class="line"> <span class="keyword">public</span> <B> B <span class="title function_">accept</span><span class="params">(TreeVisitor<B> v)</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">interface</span> <span class="title class_">TreeVisitor</span><B> {</span><br><span class="line"> <span class="keyword">public</span> B <span class="title function_">visitLeaf</span><span class="params">(Leaf t)</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Leaf</span> <span class="keyword">implements</span> <span class="title class_">Tree</span> {</span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">final</span> <span class="type">int</span> value;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="title function_">Leaf</span><span class="params">(<span class="type">int</span> value)</span> {</span><br><span class="line"> <span class="built_in">this</span>.value = value;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <B> B <span class="title function_">accept</span><span class="params">(TreeVisitor<B> v)</span> {</span><br><span class="line"> <span class="keyword">return</span> v.visitLeaf(<span class="built_in">this</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure> + +<p>要是从字面上直接翻译成OCaml:</p> +<figure class="highlight ocaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="keyword">virtual</span> tree =</span><br><span class="line"> <span class="keyword">object</span></span><br><span class="line"> <span class="keyword">method</span> <span class="keyword">virtual</span> accept : <span class="symbol">'a</span> . <span class="symbol">'a</span> tree_visitor -> <span class="symbol">'a</span></span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">and</span> <span class="keyword">virtual</span> [<span class="symbol">'a</span>] tree_visitor =</span><br><span class="line"> <span class="keyword">object</span></span><br><span class="line"> <span class="keyword">method</span> <span class="keyword">virtual</span> visit_leaf : (leaf -> <span class="symbol">'a</span>)</span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">and</span> leaf (i : <span class="built_in">int</span>) =</span><br><span class="line"> <span class="keyword">object</span> (self)</span><br><span class="line"> <span class="keyword">method</span> get = i</span><br><span class="line"></span><br><span class="line"> <span class="keyword">method</span> accept (v : <span class="symbol">'a</span> tree_visitor) : <span class="symbol">'a</span> =</span><br><span class="line"> v#visit_leaf (self :> leaf)</span><br><span class="line"> <span class="keyword">end</span></span><br></pre></td></tr></table></figure> + +<p>是行不通滴:</p> +<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">File "visitor.ml", line 3, characters 28-54:</span><br><span class="line">3 | method virtual accept : 'a . 'a tree_visitor -> 'a</span><br><span class="line"> ^^^^^^^^^^^^^^^^^^^^^^^^^^</span><br><span class="line">Error: The universal type variable 'a cannot be generalized:</span><br><span class="line"> it escapes its scope.</span><br></pre></td></tr></table></figure> + +<p>OCaml的类在定义时是单态的,比如:</p> +<figure class="highlight ocaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> [<span class="symbol">'a</span>] c (x:<span class="symbol">'a</span>) = </span><br><span class="line"> <span class="keyword">object</span></span><br><span class="line"> <span class="keyword">method</span> x = x</span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"><span class="keyword">and</span> d = </span><br><span class="line"> <span class="keyword">object</span></span><br><span class="line"> <span class="keyword">method</span> strange = (<span class="keyword">new</span> c <span class="number">0</span>)#x</span><br><span class="line"> <span class="keyword">end</span></span><br></pre></td></tr></table></figure> + +<p>这里c是:</p> +<figure class="highlight ocaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> [<span class="symbol">'a</span>] c : <span class="symbol">'a</span> -> <span class="keyword">object</span> <span class="keyword">constraint</span> <span class="symbol">'a</span> = <span class="built_in">int</span> <span class="keyword">method</span> x : <span class="symbol">'a</span> <span class="keyword">end</span></span><br></pre></td></tr></table></figure> + +<p>因为在d里面<code>new c 0</code>了一个 <code>int c</code> 的对象。</p> +<p>所以正确的写法应该是:</p> +<figure class="highlight ocaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="keyword">virtual</span> [<span class="symbol">'a</span>, <span class="symbol">'leaf</span>, <span class="symbol">'node</span>, <span class="symbol">'empty</span>] open_tree_visitor = </span><br><span class="line"> <span class="keyword">object</span></span><br><span class="line"> <span class="keyword">method</span> <span class="keyword">virtual</span> visit_leaf : <span class="symbol">'leaf</span> -> <span class="symbol">'a</span></span><br><span class="line"> <span class="keyword">method</span> <span class="keyword">virtual</span> visit_node : <span class="symbol">'node</span> -> <span class="symbol">'a</span></span><br><span class="line"> <span class="keyword">method</span> <span class="keyword">virtual</span> visit_empty : <span class="symbol">'empty</span> -> <span class="symbol">'a</span></span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="keyword">virtual</span> tree = </span><br><span class="line"> <span class="keyword">object</span></span><br><span class="line"> <span class="keyword">method</span> <span class="keyword">virtual</span> accept : <span class="symbol">'a</span> .</span><br><span class="line"> (<span class="symbol">'a</span>, <span class="symbol">'leaf</span>, <span class="symbol">'node</span>, <span class="symbol">'empty</span>) open_tree_visitor -> <span class="symbol">'a</span></span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">and</span> leaf (i : <span class="built_in">int</span>) = </span><br><span class="line"> <span class="keyword">object</span> (self:<span class="symbol">'self</span>)</span><br><span class="line"> <span class="keyword">inherit</span> tree</span><br><span class="line"> <span class="keyword">method</span> get = i</span><br><span class="line"> <span class="keyword">method</span> accept v = v#visit_leaf (self :> leaf)</span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">and</span> node (x : tree) (y: tree) = </span><br><span class="line"> <span class="keyword">object</span> (self:<span class="symbol">'self</span>)</span><br><span class="line"> <span class="keyword">inherit</span> tree</span><br><span class="line"> <span class="keyword">method</span> left = x</span><br><span class="line"> <span class="keyword">method</span> right = y</span><br><span class="line"> <span class="keyword">method</span> accept v = v#visit_node (self :> node)</span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">and</span> empty = </span><br><span class="line"> <span class="keyword">object</span> (self:<span class="symbol">'self</span>)</span><br><span class="line"> <span class="keyword">inherit</span> tree</span><br><span class="line"> <span class="keyword">method</span> accept v = v#visit_empty (self :> empty)</span><br><span class="line"> <span class="keyword">end</span></span><br></pre></td></tr></table></figure> +</div> + +<script> + window.onload = detectors(); +</script> + <div class="post-footer"> + <div class="h-line-primary"></div> + <nav class="post-nav"> + <div class="prev-item"> + + </div> + <div class="next-item"> + + <div class="icon arrow-right"></div> + <div class="post-link"> + <a href="/2023/06/28/%E9%9A%90%E8%97%8F%E4%B8%80%E4%BA%9BOCaml-Effect%E7%9A%84%E6%9C%BA%E5%88%B6%EF%BC%8C%E8%AE%A9%E5%85%B6%E8%AF%AD%E6%B3%95%E5%9C%A8%E7%B2%BE%E7%A5%9E%E4%B8%8A%E6%9B%B4%E6%8E%A5%E8%BF%91delimcc/">Next</a> + </div> + + </div> + </nav> +</div> + + + <div class="post-comment"> + + + + + + + +</div> + + +</article> + </div> + </div> + + <div class="footer"> + <div class="flex-container"> + <div class="footer-text"> + + + | + + + 希望路过的人可以添点柴火让这里暖和点 + + </div> + </div> +</div> + + </div> + + + + + </body> +</html> |
