相关疑难解决方法(0)

Haskell的隐藏功能

Haskell编程语言的一些鲜为人知但有用的特性是什么.(我理解语言本身鲜为人知,但与我一起工作.即使是对Haskell中简单事物的解释,比如用一行代码定义Fibonacci序列,也会被我推翻.)

  • 尝试限制Haskell核心的答案
  • 每个答案一个功能
  • 举一个示例和该功能的简短描述,而不仅仅是文档的链接
  • 使用粗体标题作为第一行标记要素

haskell

32
推荐指数
24
解决办法
2万
查看次数

为什么Haskell的作用域类型变量不允许在模式绑定中绑定类型变量?

我注意到GHC ScopedTypeVariables能够在函数模式中绑定类型变量,但不能让模式.

作为一个最小的例子,考虑类型

data Foo where Foo :: Typeable a  => a -> Foo
Run Code Online (Sandbox Code Playgroud)

如果我想访问Foo中的类型,则以下函数无法编译:

fooType :: Foo -> TypeRep
fooType (Foo x) =
    let (_ :: a) = x
    in typeRep (Proxy::Proxy a)
Run Code Online (Sandbox Code Playgroud)

但是使用这个技巧将类型变量绑定移动到函数调用,它可以正常工作:

fooType (Foo x) =
    let helper (_ :: a) = typeRep (Proxy::Proxy a)
    in helper x
Run Code Online (Sandbox Code Playgroud)

由于let绑定实际上是伪装的函数绑定,为什么上面两个代码片段不等同?

(在这个例子中,其他解决方案是创建TypeRepwith typeOf x,或者直接绑定变量,就像x :: a在顶级函数中一样.这些选项都不在我的实际代码中,并且使用它们不回答问题.)

haskell ghc

4
推荐指数
1
解决办法
484
查看次数

存在构造函数的模式绑定

在编写Haskell作为之前接触过Lisp的程序员时,我注意到一些奇怪的事情,我无法理解.

编译好:

{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ExistentialQuantification #-}
data Foo = forall a. Show a => Foo { getFoo :: a }

showfoo :: Foo -> String
showfoo Foo{getFoo} = do
  show getFoo
Run Code Online (Sandbox Code Playgroud)

但这失败了:

{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ExistentialQuantification #-}
data Foo = forall a. Show a => Foo { getFoo :: a }

showfoo :: Foo -> String
showfoo foo = do
  let Foo{getFoo} = foo
  show getFoo
Run Code Online (Sandbox Code Playgroud)

对我而言,第二个片段失败的原因并不明显.

问题是:

我是否因为haskell不是homoiconic这一事实而错过了某些内容或阻止了这种行为?

我的理由是,鉴于:

  1. Haskell需要将记录模式匹配实现为编译器扩展,因为它可以选择使用语法而不是数据.

  2. 函数头或let子句中的匹配是两种特殊情况.

很难理解这些特殊情况,因为它们既不能实现也不能直接用语言本身查找. …

haskell homoiconicity

1
推荐指数
1
解决办法
130
查看次数

标签 统计

haskell ×3

ghc ×1

homoiconicity ×1