在OO Haskell中指定数据类型

时间:2012-02-03 06:04:52

标签: haskell

在这个Haskell代码中,构造函数参数(长度和宽度)可以是任何数据类型(如Int,Char等)。有没有办法可以明确指定长度和宽度的数据类型? 如何指定函数的返回类型getLength

{-# LANGUAGE EmptyDataDecls, DeriveDataTypeable, TemplateHaskell #-}
{-# OPTIONS_GHC -fcontext-stack=100 #-}

module Rectangle where

import OOHaskell

$(label "getLength")
$(label "getWidth")
$(label "incr")
$(label "lengthenBy")
$(label "setLength")
$(label "setWidth")
$(label "show'")

rectangle length width self
 = do
     lengthRef <- newIORef length
     widthRef <- newIORef width
     return $
          getLength      .=. readIORef lengthRef
      .*. getWidth      .=. readIORef widthRef
      .*. setLength      .=. writeIORef lengthRef
      .*. setWidth      .=. writeIORef widthRef
      .*. lengthenBy    .=. (\dl ->
              do
             length <- self # getLength
             (self # setLength) (length + dl))
      .*. incr          .=. (self # lengthenBy) (1)
      .*. show'         .=. printLn ("Length : "<< self # getLength<<" Width : "<< self # getWidth)
      .*. emptyRecord

主要应该有效(如果是这样的话):

main = do
   c1 <- mfix $ rectangle 0 0
   c2 <- mfix $ rectangle 0 0
   c3 <- mfix $ rectangle 0 0
   c1# setWidth $ 3
   c2# setWidth $ 2
   c3# setWidth $ 2
   c1# incr
   c2# incr
   c1# incr
   c1# show'
   c3# show'

但即使以这种方式编写主要内容也是可行的(因为宽度不能是字符)。

main = do
   c1 <- mfix $ rectangle 0 'a'
   c2 <- mfix $ rectangle 0 'b'
   c3 <- mfix $ rectangle 0 'c'
   c1# setWidth $ 'd'
   c2# setWidth $ 'e'
   c3# setWidth $ 'f'
   c1# incr
   c2# incr
   c1# incr
   c1# show'
   c3# show'

3 个答案:

答案 0 :(得分:1)

  

有没有办法可以明确指定长度和宽度的数据类型?

是:

rectangle :: TypeOfLength -> TypeOfWidth -> TypeOfSelf -> ReturnTypeOfRectangle
rectangle length width self = ...
  

如何指定函数getLength的返回类型?

我从不使用OOHaskell所以我不确定这一点。基本上,您可以声明函数期望的类型(作为参数)及其返回类型。语法如上面的矩形,返回类型总是最右边的。

参考:http://en.wikibooks.org/wiki/Haskell/Type_basics#Type_signatures_in_code

答案 1 :(得分:1)

您始终可以在构造函数中添加类型注释,例如在创建IORef时,类似于:

widthRef :: IORef Int <- newIORef width

或函数参数width本身的等价物。

答案 2 :(得分:1)

假设这一切都是类型安全的,getLength的返回类型将匹配lengthRef的内容,所以你只需要在某个地方添加一个约束该类型的类型签名,以及应该从中正确推断出getLength

例如,您可以在创建lengthRef时指定类型:

lengthRef <- newIORef (length :: Int)
相关问题