功能编程范例是否有可视化建模语言或风格?

时间:2009-09-01 19:31:29

标签: programming-languages haskell modeling functional-programming

UML是一个旨在用软件建模的标准,它将用OO语言编写,并与Java携手并进。它是否可能用于模拟软件的功能编程范式?考虑到嵌入的视觉元素,哪些图表会变得有用?

是否有针对函数式编程的建模语言,更具体地说是Haskell?您建议使用哪些工具组合图表?

由OP于2009年9月2日编辑:

我正在寻找的是代码中发生的最直观,最轻的代表。易于遵循的图表,视觉模型不一定针对其他程序员。我很快就会在Haskell开发一款游戏,但由于这个项目是我的毕业结论工作,我需要介绍一下拟议解决方案的某种形式化。我想知道是否有相当于UML + Java标准,但对于Haskell。 我是否应该坚持使用故事板,书面描述,非正式化图表(一些浅层流程图图像),非正式用例描述?

2012年6月21日由jcolebrand编辑:

请注意,提问者原本想要一个视觉元素,现在我们已经有三年了,我们正在寻找更多/更好的工具。原始答案中没有一个真正涉及“视觉隐喻设计工具”的概念,所以...这就是新的赏金所要提供的。

11 个答案:

答案 0 :(得分:43)

我相信Haskell的建模语言叫做“math”。它通常在学校教授。

答案 1 :(得分:30)

是的,Haskell有广泛使用的建模/规范语言/技术。 他们不是视觉上的。

在Haskell中,类型提供部分规范。 有时,此规范完全确定了意义/结果,同时留下了各种实现选择。 超越Haskell到具有依赖类型的语言,如Agda& Coq(以及其他),类型作为完整的规范更常用。

如果类型不够,请添加正式规范,这通常采用简单的功能形式。 (因此,我相信,Haskell选择的建模语言是Haskell本身或“数学”的答案。) 在这种形式中,您提供了一个功能定义,该定义针对清晰度和简单性进行了优化,而不是为了提高效率。 该定义甚至可能涉及不可计算的操作,例如无限域上的函数相等性。 然后,逐步将规范转换为高效可计算功能程序的形式。 每一步都保留语义(外延),因此最终形式(“实现”)保证在语义上等同于原始形式(“规范”)。 您将看到此过程以各种名称引用,包括“程序转换”,“程序派生”和“程序计算”。

典型推导中的步骤主要是“等式推理”的应用,增加了一些数学归纳(和共同归纳)的应用。 能够执行这种简单有用的推理是函数式编程语言的主要动机,并且它们的有效性归功于“真正的函数式编程”的“外延”性质。 (术语“指示性”和“真正有用的”来自Peter Landin的开创性论文The Next 700 Programming languages。) 因此,纯函数式编程的号召力曾经“对于等式推理有利”,尽管我现在几乎没有听到这种描述。 在Haskell中,外延对应于IO以外的类型以及依赖IO的类型(例如STM)。 虽然外延/非IO类型适用于正确的等式推理,但IO /非外延类型被设计为不正确的等式推理。

我在Haskell工作中尽可能经常使用的特定版本的规范派生是我称之为“语义类型态射”(TCM)。 其中的想法是为数据类型提供语义/解释,然后使用TCM原则通过类型类实例确定(通常唯一地)大多数或所有类型的功能的含义。 例如,我说Image类型的含义是来自2D空间的函数。 然后,TCM原则告诉我MonoidFunctorApplicativeMonadContrafunctorComonad个实例的含义,到那些功能的实例。 这是对图像有用的功能的很多,具有非常简洁和引人注目的规格! (规范是语义功能加上语义TCM原则必须包含的标准类型列表。) 然而,我对如何表示图像拥有极大的自由,而语义TCM原则消除了抽象泄漏。 如果您很想看到这个原则的实例,请查看论文Denotational design with type class morphisms

答案 2 :(得分:21)

我们使用定理证明器进行正式建模(带验证),例如Isabelle或Coq。在推导“低级”Haskell实现之前,有时我们使用特定于域的语言(例如Cryptol)来执行高级设计。

通常我们只使用Haskell作为建模语言,并通过重写来实现实际的实现。

QuickCheck属性也在设计文档中起作用,同时还有类型和模块分解。

答案 3 :(得分:13)

是的,Haskell。

我得到的印象是,使用函数式语言的程序员在考虑他们的设计时不需要简化他们的选择语言,这是一种(相当简单的)方式来查看UML为你做的事情。

答案 4 :(得分:6)

我观看了一些视频采访,并阅读了一些采访,其中包括erik meijer和simon peyton-jones。似乎在建模和理解问题域时,它们使用类型签名,尤其是函数签名。

序列图(UML)可能与函数的组成有关。 静态类图(UML)可能与类型签名有关。

答案 5 :(得分:5)

在Haskell中,您可以按类型进行建模。

首先编写函数,类和数据签名而不进行任何实现,并尝试使类型适合。下一步是QuickCheck。

E.g。模拟排序:

class Ord a where
    compare :: a -> a -> Ordering

sort :: Ord a => [a] -> [a]
sort = undefined

然后测试

prop_preservesLength l = (length l) == (length $ sort l)
...

最后实施......

答案 6 :(得分:4)

虽然不是建议使用(因为它似乎无法下载),但HOPS system可视化术语图表,这通常是功能程序的方便表示。

HOPS screenshot

它也可以被认为是一种设计工具,因为它支持记录程序以及构建程序;我相信如果您愿意,也可以逐步重写术语,以便您可以看到它们unfold

不幸的是,我相信它已经不再积极开发了。

答案 7 :(得分:2)

我意识到我已经迟到了,但是如果有人觉得它有用,我还是会给出答案。

我想我会选择SADT / IDEF0之类的系统方法。

这些图表可以使用Linux,Windows和MacOS上提供的Dia程序进行。

答案 8 :(得分:2)

您可以使用Hideki John Reekie的Realtime Signal Processing: Dataflow, Visual, and Functional Programming中描述的数据流过程网络模型

例如像(Haskell)这样的代码:

import sys
import csv
#Phidget specific imports
from Phidgets.PhidgetException import PhidgetException
from Phidgets.Devices.GPS import GPS
from Phidgets.Phidget import PhidgetLogLevel



#Create an accelerometer object
try:
gps = GPS()
except RuntimeError as e:
print("Runtime Exception: %s" % e.details)
print("Exiting....")
exit(1)

#Information Display Function
def displayDeviceInfo():
print("|------------|----------------------------------|--------------|-------           -----|")
print("|- Attached -|-              Type              -|- Serial No. -|-          Version -|")
print("|------------|----------------------------------|--------------|------------|")
  print("|- %8s -|- %30s -|- %10d -|- %8d -|" % (gps.isAttached(),       gps.getDeviceName(), gps.getSerialNum(), gps.getDeviceVersion()))
print("|------------|----------------------------------|--------------|------------|")

#Event Handler Callback Functions
def GPSAttached(e):
attached = e.device
print("GPS %i Attached!" % (attached.getSerialNum()))

def GPSDetached(e):
detached = e.device
 print("GPS %i Detached!" % (detached.getSerialNum()))

def GPSError(e):
try:
source = e.device
print("GPS %i: Phidget Error %i: %s" % (source.getSerialNum(), e.eCode,       e.description))
except PhidgetException as e:
print("Phidget Exception %i: %s" % (e.code, e.details))

def GPSPositionChanged(e):
source = e.device
print("%f, %f, %f") %(e.latitude, e.longitude, e.altitude)
w=csv.writer(file(r'test6.csv','wb'), delimiter=';')
some_values=[(e.latitude,e.longitude,e.altitude)]
w.writerows(some_values)



def GPSPositionFixStatusChanged(e):
source = e.device
if e.positionFixStatus:
status = "FIXED"
else:
status = "NOT FIXED"
print("GPS %i: Position Fix Status: %s" % (source.getSerialNum(), status))

#Main Program Code

try:
#logging example, uncomment to generate a log file
#gps.enableLogging(PhidgetLogLevel.PHIDGET_LOG_VERBOSE, "phidgetlog.log")


gps.setOnAttachHandler(GPSAttached)
gps.setOnDetachHandler(GPSDetached)
gps.setOnErrorhandler(GPSError)
gps.setOnPositionChangeHandler(GPSPositionChanged)
gps.setOnPositionFixStatusChangeHandler(GPSPositionFixStatusChanged)
except PhidgetException as e:
print("Phidget Exception %i: %s" % (e.code, e.details))
print("Exiting....")
exit(1)

print("Opening phidget object....")

try:
gps.openPhidget()
except PhidgetException as e:
print("Phidget Exception %i: %s" % (e.code, e.details))
print("Exiting....")
exit(1)

print("Waiting for attach....")

try:
gps.waitForAttach(10000)
except PhidgetException as e:
print("Phidget Exception %i: %s" % (e.code, e.details))
try:
gps.closePhidget()
except PhidgetException as e:
print("Phidget Exception %i: %s" % (e.code, e.details))
print("Exiting....")
exit(1)
print("Exiting....")

视觉表现形式为:

enter image description here

答案 9 :(得分:1)

使用数学建模Haskell有什么意义?我认为Haskell的重点在于它与数学有着如此密切的关系,以至于数学家可以选择并运行它。为什么要将一种语言翻译成自己?

使用其他函数式编程语言(f#)时,我在描述大块的白板上使用了图表,然后使用类使用UML以OO方式对系统进行建模。 f#中的构建块中存在轻微的未匹配(将类拆分为数据结构和作用于它们的函数)。但是从商业角度来理解它是一种享受。我想补充一点,这个问题是面向业务/面向Web的,并且不知道该技术对于更具财务性的东西有多好。我想我可能会将函数捕获为没有状态的对象,它们应该很好地适应。

这完全取决于您所在的域名。

答案 10 :(得分:0)

我使用USL - 通用系统语言。我正在学习Erlang,我觉得它非常适合。

太糟糕了,文档非常有限,没有人使用它。 更多信息here