小编Tho*_*ook的帖子

Kotlin 高阶函数组合

我试图弄清楚如何在 Kotlin 中将一个函数声明性地定义为其他两个函数的组合,但我很挣扎。这是我的代码:

fun compose(a: (Int, Int) -> Int, b: (Int, Int) -> Int): Int {
    return a.invoke() + b.invoke()
}
Run Code Online (Sandbox Code Playgroud)

compose 函数的想法是,它将接受两个函数作为输入(这两个函数都接受两个 Int 并返回一个 Int)并返回两个传递函数的结果之和。问题是我必须调用传递的函数来计算它们的总和(显然大声笑)但我不知道我希望在 compose 方法内部调用的值(它们是传递给函数的值)。

我在这里完全错过了什么吗?我知道这在像 Haskell 这样的语言中是可能的,在 Kotlin 中是否可能?

kotlin

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

Threenpenny gui - 在点击时捕获鼠标坐标并使用它们来构建一些状态

我想达到的目标:

每次用户单击画布时,从该单击中获取鼠标坐标以构造 aPoint x y并将此状态存储在 a 中[Point],以便在稍后用户单击按钮时我可以将其[Point]用作某些功能的输入。

我所做的:

我已经定义了一个Point数据类型,有一个像这样的单值构造函数:

data Point = Point {
  x :: Int,
  y :: Int
} deriving (Show, Eq)
Run Code Online (Sandbox Code Playgroud)

我已经设置了一个三便士UI(monad?)来定义用户界面,一个简单的400 x 400 canvas和一个button

import qualified Graphics.UI.Threepenny as UI
import Graphics.UI.Threepenny.Core
import Control.Monad

canvasSize = 400

setup :: Window -> UI ()
setup window = do
  return window # set title "Haskell GUI"

  canvas <- UI.canvas
    # set UI.height canvasSize
    # set …
Run Code Online (Sandbox Code Playgroud)

haskell functional-programming frp threepenny-gui

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

调用 flow.single() 时何时抛出 NoSuchElementException

假设我有一个像这样的 API:

interface Foo {
   val barFlow: Flow<Bar>
}
Run Code Online (Sandbox Code Playgroud)

我像这样消费它:

class FooConsumer(private val foo: Foo) {
   init {
       CoroutineScope(Dispatchers.IO).launch {
           val bar = foo.barFlow.single()
           println("Collected bar: $bar)
       }
   }
}
Run Code Online (Sandbox Code Playgroud)

根据文档,如果流为空,则可以抛出singlea 。NoSuchElementException然而,这让我很困惑,因为流上的终端操作将“等待”流的元素被发出。那么调用如何single知道流中没有元素呢?也许某个元素还没有被发射?

我的意思是,在幕后,调用single是在进行检查之前收集源流。因此,在执行 null 检查之前,必须至少发出 1 项,以便 null 检查永远不会成功,并且NoSuchElementException永远不会抛出 a (对于流属于不可为 null 类型的情况)。

那么NoSuchElementException只有可空类型的流才有可能吗?

这是源代码single

/**
 * The terminal operator, that awaits for one and only one value to be published.
 * Throws [NoSuchElementException] for empty …
Run Code Online (Sandbox Code Playgroud)

kotlin kotlin-coroutines kotlin-flow

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

Haskell中符号字符的语法和语义

我正在学习Haskell.

学习新语言时,我的标准技术之一是实现Hello World遗传算法,该算法尝试通过与某些输入字符串匹配的遗传算法技术生成字符串.

由于我对Haskell的经验不足(我必须比较最接近的是Kotlin)我搜索了一个示例代码,因此我可以将我对基本遗传算法的现有理解与代码相匹配,并根据我已经在进行的阅读对Haskell的一些理解.对语言的研究.

我遇到了这个教程:https://www.arcadianvisions.com/blog/2011/haskell-genetic-algorithm-hello-world.html

我设置了我的环境之后我在原子中转录它,每个部分我都不明白我做了一个快速谷歌,如果我在15分钟后不理解语法/语义我将继续抄写意图后来赶上那些特殊的部分.

所以,我理解了大部分代码,例如函数应用程序的顺序,monads(我认为我几乎与monads一起),数据类型,函数类型,currying,类型替换等.但是,有几个语法位/语义,我在阅读/研究中没有看到,不知道他们做了什么,但他们在我上面链接的代码示例中出现了很多.我希望有人可以向我解释一下:

(++)
(:)
<$>
<*>
(,)
(x !!)
p@(info@())
Run Code Online (Sandbox Code Playgroud)

我假设()<>是一些特殊的语法,其中的东西是语义的?当我将它们悬停在原子上时(我正在使用atom-haskell-ghc)我可以看到Functor f => Applicative (f :: * -> *) where <*> :: f (a -> b) -> f a -> f b哪种类型看起来像monad,但我并不真正理解消费端的奇怪语法/语义.我是否应该将这些视为另一个函数(带有奇怪的中缀别名?).

以下是展示上述几个例子的具体行:

mate :: RandomGen g => Gene -> Gene -> Rand g Gene
mate gene1 gene2 = (++) <$> flip take gene1 <*> flip drop gene2 <$> pivot
  where pivot = getRandomR (0, length …
Run Code Online (Sandbox Code Playgroud)

haskell

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

AndroidX与DataBinding Android不兼容

好的,我的任务是将项目迁移到AndroidX,以减少项目中支持库的混乱情况。我已经根据官方文档启用了AndroidX,但是现在尝试通过相应的自动生成的Binding类(通过在模块gradle中启用数据绑定而创建)来充气视图时,出现了运行时错误。

挖掘自动生成的源代码时,我遇到了这种方法,该方法导致代码抛出:

   public List<DataBinderMapper> collectDependencies() {
        ArrayList<DataBinderMapper> result = new ArrayList(1);
        result.add(new com.android.databinding.library.baseAdapters.DataBinderMapperImpl());
        return result;
    }
Run Code Online (Sandbox Code Playgroud)

如您所见,自动生成的代码正在尝试从com.android.databinding程序包中实例化一个类,但是该程序包在输出APK中不存在,因为我已从gradle中删除了支持依赖项(因为AndroidX应该替换了它们)。我可以看到androidx有一个数据绑定包,所以我假设上面的自动生成的代码应该引用androidx.databinding包,但是没有。

这是工具中的错误还是我配置错误?

这是我的gradle文件(出于安全原因省略了一些位):

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'

//These variable refer to release builds so make sure they are correct. If you need to override them
//for some specific development needs then use variables that can be passed to gradle on command line.
String releaseVersionName = '1.0.0'
int releaseVersionCode = 1
int releaseMinSdk = 18 …
Run Code Online (Sandbox Code Playgroud)

android android-databinding androidx

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

Kotlin 看似递归的编译模板类型

在工作中进行代码审查并遇到了我以前从未见过的模板类型的使用。乍一看,代码似乎不应该编译,因为定义似乎是递归的。我将其归结为最简单的可验证示例:

interface Bar<T>
interface Foo<T: Bar<T>> // Surely this is recursive?
Run Code Online (Sandbox Code Playgroud)

我对模板类型如何工作的理解是:

interface Foo<T>-一个FooT,没有任何限制

interface Foo<T : Bar>- a Fooof T,其中T被限制为 aBar

假设我上面说的是真的,那么这对我来说没有意义:

interface Bar<T>- a Barof T, 没有约束T

interface Foo<T: Bar<T>>- a Fooof T,其中T被限制为 aBar<T>

哦哦,如何T定义Bar<T>?。

我们知道T是 a Bar<T>,所以如果我们替换Tin Bar<T>,那么它就是 a Bar<Bar<T>>

我们还没有解决TBar......为了便于讨论,让我们来代替 …

generics templates kotlin

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

在C#中查询字典的优雅方式

我正在尝试创建一种优雅且可扩展的查询字典的方法,该字典将枚举映射到一组字符串.

所以我有这个SearchFragments包含字典的类.然后我想要一个方法,其中这个类的消费者可以简单地问"HasAny",这是我正在努力的位,只需传递一些查询,如表达式并获得布尔答案.

public class SearchFragments
{
    private readonly IDictionary<SearchFragmentEnum, IEnumerable<string>> _fragments;

    public SearchFragments()
    {
        _fragments = new Dictionary<SearchFragmentEnum, IEnumerable<string>>();
    }

    public bool HasAny(IEnumerable<SearchFragmentEnum> of)
    {
        int has = 0;
        _fragments.ForEach(x => of.ForEach(y => has += x.Key == y ? 1 : 0));
        return has >= 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

目前的问题是,这个类的消费者现在必须构建一个IEnumerable<SearchFragmentEnum>可能非常混乱的消费者.

我正在寻找的是消费代码将能够写出以下内容:

searchFragments.HasAny(SearchFragmentEnum.Name, SearchFragmentEnum.PhoneNumber)
Run Code Online (Sandbox Code Playgroud)

但是这个参数列表的大小可能会有所不同(没有我必须在SearchFragments类中为每个可能的组合编写方法重载(这样如果SearchFragmentEnum在将来的日期添加新值,我将不必更新类.

c# syntax open-closed-principle

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

Haskell依赖地狱

我正在尝试在Haskell项目中包含特定版本的库.该库是住宿和早餐(用于martix操作),但我需要特定版本0.4.3修复了乘法实现的错误.

所以,我的stack.yaml看起来像这样:

flags: {}
extra-package-dbs: []
packages:
- .
extra-deps:
- bed-and-breakfast-0.4
- base-4.6.0.1
resolver: lts-12.8
Run Code Online (Sandbox Code Playgroud)

但是我在构建时遇到了这个错误:

Error: While constructing the build plan, the following exceptions were encountered:

In the dependencies for bed-and-breakfast-0.4:
    base-4.11.1.0 from stack configuration does not match >=4.5 && <4.7  (latest matching version
                  is 4.6.0.1)
needed due to realworldhaskell-0.1.0.0 -> bed-and-breakfast-0.4

Some different approaches to resolving this:


  * Set 'allow-newer: true' to ignore all version constraints and build anyway.

  * Consider trying 'stack solver', which uses the …
Run Code Online (Sandbox Code Playgroud)

haskell haskell-stack

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

为什么(。)称为中缀。而不是`(。)`

我了解到可以通过两种方式调用函数:前缀和中缀。例如,说我创建了这个函数:

example :: [Char] -> [Char] -> [Char]
example x y = x ++ " " ++ y
Run Code Online (Sandbox Code Playgroud)

我可以这样称呼它为前缀:

example "Hello" "World"
Run Code Online (Sandbox Code Playgroud)

或像这样的中缀:

"Hello" `example` "World"
Run Code Online (Sandbox Code Playgroud)

两者都会导致代表字符串的字符列表"Hello World"

但是,我现在正在学习函数组成,并且遇到了如下定义的函数:

(.) :: (b -> c) -> (a -> b) -> a -> c
Run Code Online (Sandbox Code Playgroud)

所以,说我想乘以三来求和。我会像这样写前缀调用:

negateComposedWithMultByThree = (.) negate (*3) 
Run Code Online (Sandbox Code Playgroud)

和infix调用类似:

negateComposedWithMultByThree = negate `(.)` (*3)
Run Code Online (Sandbox Code Playgroud)

但是,虽然前缀调用可以编译,但infix调用却不会,而是显示错误消息:

错误:解析输入'('

看来,为了调用compose infix,我需要省略方括号并这样称呼它:

negateComposedWithMultByThree = negate . (*3)
Run Code Online (Sandbox Code Playgroud)

谁能对此有所启示?为什么"Hello" `example` "World"同时negate `(.)` (*3)不?

另外,如果我尝试使用这样的签名来实现自己的功能:

(,) :: Int -> Int …
Run Code Online (Sandbox Code Playgroud)

haskell

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

Kotlin递归堆栈溢出

我在Kotlin写了这个递归函数:

fun recursive(target: String, population: Population, debugFun: (String) -> Unit) : Population {
    if (population.solution(target).toString() == target) {
        return population
    }
    debugFun.invoke(population.solution(target).toString())
    return recursive(target, population.evolve(target), debugFun)
}
Run Code Online (Sandbox Code Playgroud)

它将运行不确定的次数(因为我使用随机性来收敛进化算法中的解决方案).我经常得到堆栈溢出.Kotlin/JVM语言的最大堆栈深度是多少?我应该非递归地编写函数吗?

stack-overflow recursion tail-recursion kotlin

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

Haskell ADT声明了float,但是当提供float时,ADT实例定义无法编译

我已经编写了这个简单的模块,其中公开了ADT PointShape

module Lib(Point, Shape) where

data Point = Point Float Float deriving (Show)
data Shape = Circle Point Float | Rectangle Point Point deriving (Show)
Run Code Online (Sandbox Code Playgroud)

然后,我写了一个main定义了一个实例Circle

module Main where

import Lib

main :: IO ()
main = do
  let circle = Circle 0.0 0.0 10.0
  print ""
Run Code Online (Sandbox Code Playgroud)

但是,它无法编译错误消息:

    Data constructor not in scope:
      Circle :: Double -> Double -> Double -> t
  |
7 |   let circle = Circle 0 0 10
  |                ^^^^^^ …
Run Code Online (Sandbox Code Playgroud)

haskell

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

在密封类上的 when 表达式中使用 `is` 会导致运行时反射吗?

在 Java 中,如果我有这样的类层次结构:

private interface Foo { }

private class FooBar implements Foo { }

private class FooZoo implements Foo { }
Run Code Online (Sandbox Code Playgroud)

然后我有一个这样的功能:

public int Return0IfFooBarElseIfFooZooReturn1ElseReturn2(Foo foo) {
    if (foo instanceof FooBar) {
        return 0;
    } else if (foo instanceof FooZoo) {
        return 1;
    } else {
        return 2;
    }
}
Run Code Online (Sandbox Code Playgroud)

在运行时,将使用反射来确定foo. 在理想的世界中,我们希望避免让我们的代码使用反射。此外,据我所知,在 Java 中无法创建密封类型层次结构,这意味着您将始终需要提供一个 else 分支来编译代码。

但是在 Kotlin 中,您可以创建一个密封的类型层次结构,如下所示:

sealed class Foo {
  object FooBar : Foo()
  object FooZoo : Foo()
}
Run Code Online (Sandbox Code Playgroud)

然后你可以编写一个 when 表达式来打开类型并返回一个像这样的值:

fun return0IfFooBarElseReturn1(foo: …
Run Code Online (Sandbox Code Playgroud)

java reflection kotlin

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