小编Mai*_*tor的帖子

折叠器的相同融合法可以应用于foldlmap吗?

我已经读过没有foldl单独的融合法.如果我猜对了,这是由于foldl实施地图的尴尬 - 这主要是由于(foldl cons nil xs)反转列表.

如果我们使用conc列表,那么foldlmap这个方面的功能要好得多:

(foldlmap list conc nil xs) -> xs
Run Code Online (Sandbox Code Playgroud)

如果我的猜测是正确的,那么应该有一个简单的融合法foldlmap.它是否正确?

haskell functional-programming mapreduce function fold

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

monad和宏有什么区别?

我读过一些monads tutoriais,他们几乎提出monad是实现操作顺序所必需的.但同样可以通过以下方式实现let:

(let*
    (   (a 1)
        (b (+ a 1))
        (c (+ b 1)))
    c)
Run Code Online (Sandbox Code Playgroud)

被禁止(实际上,我为了说明目的写了这个脑谜,请参阅Will Ness的评论):

((lambda (c) c)
    ((lambda (b) (+ b 1)) 
        ((lambda (a) (+ a 1))
            1)))
Run Code Online (Sandbox Code Playgroud)

那么如果这个宏能够实现排序,那么如何实现排序需要monad呢?

macros monads scheme haskell functional-programming

2
推荐指数
3
解决办法
859
查看次数

编写此函数的正确(有效)方法是什么?

以下函数返回从根节点到树的最深节点的可能路径列表:

paths :: Tree a -> [[a]]
paths (Node element []) = [[element]]
paths (Node element children) = map (element :) $ concat $ map paths children
Run Code Online (Sandbox Code Playgroud)

这在纸面上看起来非常低效,因为它concat具有可怕的复杂性.是否可以在不使用中间数据结构(如序列)的情况下以较低的复杂度重写此函数?

编辑:说实话,我知道可以通过以下方式避免连接的O(n)/循环复杂性:

  1. 在递归时构建路径(列表);
  2. 仅当您到达最后一个递归级别时,将路径追加到全局"结果"列表.

这是一个JavaScript实现,说明了这个算法:

function paths(tree){
    var result = [];
    (function go(node,path){
        if (node.children.length === 0)
            result.push(path.concat([node.tag]));
        else
            node.children.map(function(child){
                go(child,path.concat([node.tag]));
            });
    })(tree,[]);
    return result;
}
console.log(paths(
    {tag: 1,
    children:[
        {tag: 2, children: [{tag: 20, children: []}, {tag: 200, children: []}]},
        {tag: 3, children: [{tag: 30, children: []}, {tag: 300, children: …
Run Code Online (Sandbox Code Playgroud)

tree recursion complexity-theory haskell data-structures

2
推荐指数
2
解决办法
217
查看次数

我可以完全禁用GHC上的类型检查,以便将其用作函数式语言的编译目标吗?

GHC在这一点上的速度惊人地快.不过,我对Haskell的类型系统不满意,所以我决定将自己的系统作为DSL来实现.现在,我想通过翻译后检查无类型lambda演算表达式来编译我的语言到Haskell,以便使用GHC的性能.唯一的问题是我的系统上的某些有效表达式无法在GHC上编译.我怎样才能避免这个问题 - 即通过告诉GHC完全禁用类型系统"我已经检查了这个,相信我"?

haskell types compilation ghc

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

如何强制在Haskell中立即调用函数?

这是我的代码:

import Data.Function.Memoize
import Debug.Trace

foo :: Int -> Int -> Int
foo a = memoFix fooMemo where 
    fooMemo f x = a + (trace (show x) cont) where
        cont = if x == 0 then 0 else x + f (x - 1)

main = do
    print $ foo 0 5
    print $ foo 0 5
    print $ foo 0 5
Run Code Online (Sandbox Code Playgroud)

我希望它打印:

3
2
1
0
6
6
6
Run Code Online (Sandbox Code Playgroud)

但是,它打印出来:

3
2
1
0
6
3
2
1
0 …
Run Code Online (Sandbox Code Playgroud)

haskell memoization lazy-evaluation

2
推荐指数
2
解决办法
135
查看次数

使用FFI从Haskell调用CUDA"Hello World"会产生错误的结果

这是标准的Hello World CUDA文件:

#include <stdio.h>
#include "hello.h"

const int N = 7;
const int blocksize = 7;

__global__ void hello_kernel(char *a, int *b) {
    a[threadIdx.x] += b[threadIdx.x];
}

#define cudaCheckError() { \
    cudaError_t e=cudaGetLastError(); \
    if(e!=cudaSuccess) { \
        printf("Cuda failure %s:%d: '%s'\n",__FILE__,__LINE__,cudaGetErrorString(e)); \
        exit(0); \
    } \
}

void hello() {
    char a[N] = "Hello ";
    int b[N] = {15, 10, 6, 0, -11, 1, 0};

    char *ad;
    int *bd;
    const int csize = N*sizeof(char);
    const int isize = N*sizeof(int); …
Run Code Online (Sandbox Code Playgroud)

haskell cuda ffi

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

如何在与Haskell的System-Fw不匹配的类型系统中编程?

我正在研究λ演算的最佳实现.有一个特定的lambda术语子集是非常有效的.它对应于具有固定点的基本仿射逻辑的类型系统.为了测试我对该算法的实现,我必须在该系统上编写适度复杂的术语.没有基础设施,这很困难.我必须使用无类型的lambda演算,然后手动添加类型; 没有检查,统一,没有类型错误.

一个想法是在Haskell中编写程序 - 从其成熟的类型检查器中获益 - 然后转换为EAL.不幸的是,System-Fw和EAL之间存在不匹配.例如,newtype由于缺少类型级别,您无法在Haskell中表达Scott编码的ADT fix.而且,Haskell是一种复杂的语言,编写Haskell->EAl编译器并不是一件容易的事.

有没有快速/脏的方法来获得该系统的工作类型检查器/推理器/统一器 - 或者至少足够接近 - 而不必自己编程?

haskell types type-systems functional-programming

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

如何在两种数据类型之间创建完美的双射?

是否存在在两种数据类型之间创建双射的策略?例如,考虑以下数据类型:

data Colbit 
    = White Colbit Colbit 
    | Black Colbit Colbit 
    | Tip

data Bits
    = B0 Bits
    | B1 Bits
    | BEnd
Run Code Online (Sandbox Code Playgroud)

加上有效元素Colbit必须具有奇数个节点(白/黑构造函数)的约束.我该如何创建地图:

toColbit :: Bits -> Colbit
fromColbit :: Colbit -> Bits
Run Code Online (Sandbox Code Playgroud)

这样,对所有人b : Bits,fromColbit (toColbit b) == b对所有人来说c : Colbit,toColbit (fromColbit c) == c?(另外,这个属性叫什么?)

algorithm haskell types functional-programming function

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

如何在Go中为不同类型实现容器?

以下代码在Go中实现了一个int列表:

package main

import "fmt"

type List struct {
    Head int
    Tail *List
}

func tail(list List) *List {
    return list.Tail
}

func main() {
    list := List{Head: 1, Tail: 
         &List{Head: 2, Tail:
         &List{Head: 3, Tail:
         nil}}}
    fmt.Println(tail(list).Head)
}
Run Code Online (Sandbox Code Playgroud)

问题是这只适用于int.如果我想要一个列表strings,我需要再次重新实现每个列表方法(例如tail)!这显然不实用,所以,这可以通过使用空接口来解决:

type List struct {
  Head interface{} // Now works for any type!
  Tail *List
}
Run Code Online (Sandbox Code Playgroud)

问题是,1.由于类型转换,这似乎要慢得多,2.它抛弃了类型安全,允许人们键入任何东西:

// This type-checks!
func main() {
    list := List{Head: 123456789 , Tail:
         &List{Head: "covfefe" , Tail: …
Run Code Online (Sandbox Code Playgroud)

generics types interface go

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

如何在不增加索引的情况下增加`Fin n`的值?

当试图mod : Nat -> (m : Nat) -> Fin m在 Idris上实现一个函数时,我注意到明显的算法不起作用,因为当循环和增加结果时,Idris 不会相信它仍在范围内。这段代码解释了这个问题:

-- (M : Nat) is the modulus, doesn't change
-- (r : Fin M) is the result, increases as you recurse
-- (n : Nat) is the dividend, the recursion stops when it is 0
-- (m : Nat) is the modulus index, when it is Zero, the result loops around
modAux : (M : Nat) -> (r : Fin M) -> (n : Nat) -> …
Run Code Online (Sandbox Code Playgroud)

agda idris

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